Skip to content

Commit

Permalink
Simplify benchmark running
Browse files Browse the repository at this point in the history
  • Loading branch information
si618 committed Mar 11, 2024
1 parent 846066a commit b44c36b
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 95 deletions.
57 changes: 23 additions & 34 deletions Benchmarks.App/BenchmarkRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,25 @@

internal static class BenchmarkRunner
{
public static IEnumerable<Summary> RunAndBuildSummaries()
{
var args = new[] { "--filter", $"Benchmarks*" };
var types = Reflection.GetBenchmarkTypes().ToArray();

return RunAndBuildSummaries(types, args);
}


public static IEnumerable<Summary> RunAndBuildSummaries(ListSettings settings)
{
var args = settings.BuildArgs();
if (args.Length < 2)
{
// ReSharper disable once LocalizableElement - Exceptions in English
throw new ArgumentOutOfRangeException(nameof(settings), "Invalid arguments");
}
var type = Reflection.GetBenchmarkTypes().First(type => type.Name == settings.Name);

return RunAndBuildSummaries([type], args);
}

public static IEnumerable<Summary> RunAndBuildSummaries(Type[] benchmarkTypes, string[] args)
{

AnsiConsole.Cursor.Move(CursorDirection.Up, 1);

Expand All @@ -18,9 +29,9 @@ public static IEnumerable<Summary> RunAndBuildSummaries(ListSettings settings)
var summaries = new List<Summary>();
AnsiConsole.Status()
.Spinner(Spinner.Known.Dots)
.Start(WaitingMessage(settings, args), _ =>
.Start(WaitingMessage(benchmarkTypes), _ =>
summaries.AddRange(
RunBenchmarks(ListSettings.BenchmarkTypes(), args)));
RunBenchmarks(benchmarkTypes, args)));

Console.SetOut(Console.Out);

Expand Down Expand Up @@ -66,41 +77,19 @@ internal static bool IsDebugConfiguration(bool warnRatherThanFail = false)
return true;
}

private static string WaitingMessage(ListSettings settings, IReadOnlyList<string> args)
private static string WaitingMessage(Type[] benchmarkTypes)
{
var message = new StringBuilder();

if (args.Count > 2)
{
message.Append("Running selected benchmarks");
}
else if (Reflection.TryGetBenchmark(ParseFilterForBenchmark(args[1]), out var benchmark))
if (benchmarkTypes.Length > 1)
{
message.Append($"Running {benchmark} for [yellow]{benchmark.Description}[/]");

if (!benchmark.HasSimilarNameAndDescription())
{
message.Append($" [gray](method: {benchmark.Name})[/]");
}
message.Append("Running benchmarks");
}
else
else if (Reflection.TryGetBenchmark(benchmarkTypes[0].Name, out var benchmark))
{
message.Append("Running benchmarks");

if (settings.Filter?.Length > 0)
{
message.Append($" matching [yellow]{settings.Filter!}[/]");
}
message.Append($"Running benchmark {benchmark.Name}");
}

return message.ToString();
}

private static string ParseFilterForBenchmark(string filter)
{
var benchmark = filter.Trim('*');
var found = Reflection.GetBenchmarkNames()
.FirstOrDefault(b => b.Equals(benchmark, StringComparison.OrdinalIgnoreCase));
return found ?? filter;
}
}
4 changes: 2 additions & 2 deletions Benchmarks.App/Commands/BenchmarkCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ public override int Execute(
[NotNull] CommandContext context,
[NotNull] ListSettings settings)
{
ConsoleWriter.WriteHeader();

if (BenchmarkRunner.IsDebugConfiguration(settings.Debug))
{
return 1;
}

AnsiConsole.WriteLine();

var summaries = BenchmarkRunner.RunAndBuildSummaries(settings);
var builder = new SpectreReportBuilder(summaries);
var report = builder.Build();
Expand Down
9 changes: 2 additions & 7 deletions Benchmarks.App/Commands/ListCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@ public override int Execute([NotNull] CommandContext context)

AnsiConsole.Cursor.Move(CursorDirection.Up, 1);

WriteBenchmarkList();

return 0;
}

private static void WriteBenchmarkList()
{
var table = new Table();

table.AddColumn("Benchmark", config => config.NoWrap = true);
Expand All @@ -38,5 +31,7 @@ private static void WriteBenchmarkList()
}

AnsiConsole.Write(table);

return 0;
}
}
53 changes: 11 additions & 42 deletions Benchmarks.App/Commands/ListSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

internal sealed class ListSettings : CommandSettings
{
[Description("Filter by Benchmarks.<Name> (* wildcards accepted)")]
[Description("Benchmark name")]
[CommandArgument(0, "[filter]")]
public string? Filter { get; init; }
public string Name { get; init; } = string.Empty;

[Description("Allow debug configuration to run - use only for development")]
[CommandOption("--debug")]
Expand All @@ -16,54 +16,23 @@ internal sealed class ListSettings : CommandSettings

public override ValidationResult Validate()
{
if (!Reflection.GetBenchmarkTypes().Any(type => type.Name == Name))
{
return ValidationResult.Error($"Benchmark not found {Name}");
}

return ValidationResult.Success();
}

public static Type[] BenchmarkTypes() =>
[.. Reflection.GetBenchmarkTypes()
.OrderBy(t => t.Name)
.ThenBy(t => t.Namespace)];

public string[] BuildArgs()
{
var args = new List<string> { "--filter" };
var args = new List<string> { "--filter", $"*{Name}*" };

// No filter means run all benchmarks for specified options
if (string.IsNullOrEmpty(Filter))
if (!string.IsNullOrEmpty(Exporters))
{
args.Add("Benchmarks*");
args.Add("--exporters");
args.Add(Exporters);
}
else
{
var benchmarks = Filter.Split(' ');

foreach (var benchmark in benchmarks)
{
if (benchmark.Contains('*'))
{
// User added wildcard so use whatever was passed
args.Add(benchmark);
}
else if (benchmark.Contains('.'))
{
// User added namespace but no wildcard so add suffix
args.Add($"{benchmark}*");
}
else
{
// No wildcard or namespace so add wildcard prefix
args.Add($"*{benchmark}");
}
}
}

if (string.IsNullOrEmpty(Exporters))
{
return [.. args];
}

args.Add("--exporters");
args.Add(Exporters);

return [.. args];
}
Expand Down
4 changes: 1 addition & 3 deletions Benchmarks.App/Commands/WorkflowCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ internal sealed class WorkflowCommand : Command
[SuppressMessage("ReSharper", "RedundantNullableFlowAttribute")]
public override int Execute([NotNull] CommandContext context)
{
ConsoleWriter.WriteHeader();

if (BenchmarkRunner.IsDebugConfiguration(true))
{
return 1;
}

var settings = new ListSettings { Exporters = "json" };

BenchmarkRunner.RunBenchmarks(ListSettings.BenchmarkTypes(), settings.BuildArgs());
BenchmarkRunner.RunBenchmarks(Reflection.GetBenchmarkTypes().ToArray(), settings.BuildArgs());

CombineBenchmarkResults();

Expand Down
3 changes: 1 addition & 2 deletions Benchmarks.App/Menus/Selections/RunAllSelection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ public override int Execute()
return 1;
}

var settings = new ListSettings();
var summaries = BenchmarkRunner.RunAndBuildSummaries(settings);
var summaries = BenchmarkRunner.RunAndBuildSummaries();
var builder = new SpectreReportBuilder(summaries);
var report = builder.Build();

Expand Down
2 changes: 1 addition & 1 deletion Benchmarks.App/Menus/Selections/RunSelection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public override int Execute()
return 1;
}

var settings = new ListSettings();
var settings = new ListSettings { Name = Benchmark.Name };
var summaries = BenchmarkRunner.RunAndBuildSummaries(settings);
var builder = new SpectreReportBuilder(summaries);
var report = builder.Build();
Expand Down
8 changes: 4 additions & 4 deletions Benchmarks.App/Reflection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ internal static class Reflection
{
public static bool TryGetBenchmark(string name, out Benchmark benchmark)
{
var found = typeof(BenchmarkBase)
.GetMembers()
.Where(m => m.GetCustomAttribute(typeof(BenchmarkInfoAttribute)) is not null)
var found = GetBenchmarkTypes()
.Select(GetBenchmark)
.Where(type => type.Name == name)
.FirstOrDefault(p =>
p.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase) ||
p.Description.Equals(name, StringComparison.InvariantCultureIgnoreCase));
Expand Down Expand Up @@ -39,7 +38,8 @@ private static Benchmark GetBenchmark(MemberInfo memberInfo)
public static IEnumerable<Type> GetBenchmarkTypes() =>
typeof(GuidPrimaryKey).Assembly
.GetTypes()
.Where(m => m.GetCustomAttribute(typeof(BenchmarkInfoAttribute)) is not null);
.Where(m => m.GetCustomAttribute(typeof(BenchmarkInfoAttribute)) is not null)
.OrderBy(t => t.Name);

public static IEnumerable<string> GetBenchmarkNames() =>
GetBenchmarkTypes().Select(type => type.Name);
Expand Down

0 comments on commit b44c36b

Please sign in to comment.