diff --git a/src/BenchmarkDotNet/Attributes/QuietModeAttribute.cs b/src/BenchmarkDotNet/Attributes/QuietModeAttribute.cs new file mode 100644 index 0000000000..ab2e7da23a --- /dev/null +++ b/src/BenchmarkDotNet/Attributes/QuietModeAttribute.cs @@ -0,0 +1,21 @@ +using BenchmarkDotNet.Configs; +using JetBrains.Annotations; +using System; + +namespace BenchmarkDotNet.Attributes +{ + /// + /// Run benchmars in quiet mode. + /// + [PublicAPI] + [AttributeUsage(AttributeTargets.Class)] + public class QuietModeAttribute : Attribute, IConfigSource + { + public IConfig Config { get; } + + public QuietModeAttribute(bool value = false) + { + Config = ManualConfig.CreateEmpty().WithOption(ConfigOptions.QuietMode, value); + } + } +} diff --git a/src/BenchmarkDotNet/Configs/ConfigExtensions.cs b/src/BenchmarkDotNet/Configs/ConfigExtensions.cs index fa0920c7f9..41c40be08a 100644 --- a/src/BenchmarkDotNet/Configs/ConfigExtensions.cs +++ b/src/BenchmarkDotNet/Configs/ConfigExtensions.cs @@ -75,6 +75,11 @@ public static class ConfigExtensions [PublicAPI] public static ManualConfig WithUnionRule(this IConfig config, ConfigUnionRule unionRule) => config.With(m => m.WithUnionRule(unionRule)); [PublicAPI] public static ManualConfig WithCultureInfo(this IConfig config, CultureInfo cultureInfo) => config.With(m => m.CultureInfo = cultureInfo); + /// + /// Run benchmars in quiet mode. + /// + [PublicAPI] public static IConfig QuietMode(this IConfig config, bool value = true) => config.WithOption(ConfigOptions.QuietMode, value); + /// /// determines if all auto-generated files should be kept or removed after running the benchmarks /// diff --git a/src/BenchmarkDotNet/Configs/ConfigOptions.cs b/src/BenchmarkDotNet/Configs/ConfigOptions.cs index 29e9e1af6f..201ee74e58 100644 --- a/src/BenchmarkDotNet/Configs/ConfigOptions.cs +++ b/src/BenchmarkDotNet/Configs/ConfigOptions.cs @@ -44,7 +44,11 @@ public enum ConfigOptions /// /// Performs apples-to-apples comparison for provided benchmarks and jobs. Experimental, will change in the near future! /// - ApplesToApples = 1 << 8 + ApplesToApples = 1 << 8, + /// + /// Run benchmars in quiet mode. + /// + QuietMode = 1 << 9 } internal static class ConfigOptionsExtensions diff --git a/src/BenchmarkDotNet/ConsoleArguments/CommandLineOptions.cs b/src/BenchmarkDotNet/ConsoleArguments/CommandLineOptions.cs index 8a52323ad2..3bd76219da 100644 --- a/src/BenchmarkDotNet/ConsoleArguments/CommandLineOptions.cs +++ b/src/BenchmarkDotNet/ConsoleArguments/CommandLineOptions.cs @@ -155,6 +155,9 @@ public bool UseDisassemblyDiagnoser [Option("apples", Required = false, Default = false, HelpText = "Runs apples-to-apples comparison for specified Jobs.")] public bool ApplesToApples { get; set; } + [Option("quiet", Required = false, Default = false, HelpText = "Run benchmars in quiet mode.")] + public bool QuietMode { get; set; } + [Option("list", Required = false, Default = ListBenchmarkCaseMode.Disabled, HelpText = "Prints all of the available benchmark names. Flat/Tree")] public ListBenchmarkCaseMode ListBenchmarkCaseMode { get; set; } diff --git a/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs b/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs index a208cbd2c6..fbd9b8d05b 100644 --- a/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs +++ b/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs @@ -245,6 +245,7 @@ private static IConfig CreateConfig(CommandLineOptions options, IConfig globalCo config.WithOption(ConfigOptions.LogBuildOutput, options.LogBuildOutput); config.WithOption(ConfigOptions.GenerateMSBuildBinLog, options.GenerateMSBuildBinLog); config.WithOption(ConfigOptions.ApplesToApples, options.ApplesToApples); + config.WithOption(ConfigOptions.QuietMode, options.QuietMode); if (options.MaxParameterColumnWidth.HasValue) config.WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(options.MaxParameterColumnWidth.Value)); diff --git a/src/BenchmarkDotNet/Running/BenchmarkRunnerClean.cs b/src/BenchmarkDotNet/Running/BenchmarkRunnerClean.cs index 0de7f8c7a9..08af9f3c88 100644 --- a/src/BenchmarkDotNet/Running/BenchmarkRunnerClean.cs +++ b/src/BenchmarkDotNet/Running/BenchmarkRunnerClean.cs @@ -151,6 +151,7 @@ private static Summary Run(BenchmarkRunInfo benchmarkRunInfo, var cultureInfo = config.CultureInfo ?? DefaultCultureInfo.Instance; var reports = new List(); string title = GetTitle(new[] { benchmarkRunInfo }); + var quietLogger = GetQuietLogger(config, logger); var consoleTitle = RuntimeInformation.IsWindows() ? Console.Title : string.Empty; logger.WriteLineInfo($"// Found {benchmarks.Length} benchmarks:"); @@ -160,8 +161,9 @@ private static Summary Run(BenchmarkRunInfo benchmarkRunInfo, UpdateTitle(totalBenchmarkCount, benchmarksToRunCount); - using (var powerManagementApplier = new PowerManagementApplier(logger)) + using (var powerManagementApplier = new PowerManagementApplier(quietLogger)) { + bool stop = false; for (int i = 0; i < benchmarks.Length && !stop; i++) @@ -187,7 +189,7 @@ private static Summary Run(BenchmarkRunInfo benchmarkRunInfo, { var statistics = report.GetResultRuns().GetStatistics(); var formatter = statistics.CreateNanosecondFormatter(cultureInfo); - logger.WriteLineStatistic(statistics.ToString(cultureInfo, formatter)); + quietLogger.WriteLineStatistic(statistics.ToString(cultureInfo, formatter)); } if (!report.Success && config.Options.IsSet(ConfigOptions.StopOnFirstError)) @@ -223,7 +225,6 @@ private static Summary Run(BenchmarkRunInfo benchmarkRunInfo, logger.WriteLine(); benchmarksToRunCount -= stop ? benchmarks.Length - i : 1; - LogProgress(logger, in runsChronometer, totalBenchmarkCount, benchmarksToRunCount); } } @@ -391,9 +392,10 @@ private static BuildResult Build(BuildPartition buildPartition, string rootArtif private static BenchmarkReport RunCore(BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, ILogger logger, IResolver resolver, BuildResult buildResult) { var toolchain = benchmarkCase.GetToolchain(); + ILogger quietLogger = !benchmarkCase.Config.Options.IsSet(ConfigOptions.QuietMode) ? logger : NullLogger.Instance; - logger.WriteLineHeader("// **************************"); - logger.WriteLineHeader("// Benchmark: " + benchmarkCase.DisplayInfo); + quietLogger.WriteLineHeader("// **************************"); + quietLogger.WriteLineHeader("// Benchmark: " + benchmarkCase.DisplayInfo); var (success, executeResults, metrics) = Execute(logger, benchmarkCase, benchmarkId, toolchain, buildResult, resolver); @@ -405,8 +407,9 @@ private static (bool success, List executeResults, List m { var executeResults = new List(); var metrics = new List(); + var quietLogger = GetQuietLogger(benchmarkCase.Config, logger); - logger.WriteLineInfo("// *** Execute ***"); + quietLogger.WriteLineInfo("// *** Execute ***"); bool analyzeRunToRunVariance = benchmarkCase.Job.ResolveValue(AccuracyMode.AnalyzeLaunchVarianceCharacteristic, resolver); bool autoLaunchCount = !benchmarkCase.Job.HasValue(RunMode.LaunchCountCharacteristic); int defaultValue = analyzeRunToRunVariance ? 2 : 1; @@ -421,7 +424,7 @@ private static (bool success, List executeResults, List m string printedLaunchCount = analyzeRunToRunVariance && autoLaunchCount && launchIndex <= 2 ? "" : " / " + launchCount; - logger.WriteLineInfo($"// Launch: {launchIndex}{printedLaunchCount}"); + quietLogger.WriteLineInfo($"// Launch: {launchIndex}{printedLaunchCount}"); // use diagnoser only for the last run (we need single result, not many) bool useDiagnoser = launchIndex == launchCount && noOverheadCompositeDiagnoser != null; @@ -499,12 +502,13 @@ private static (bool success, List executeResults, List m private static ExecuteResult RunExecute(ILogger logger, BenchmarkCase benchmarkCase, BenchmarkId benchmarkId, IToolchain toolchain, BuildResult buildResult, IResolver resolver, IDiagnoser diagnoser, int launchIndex) { + var quietLogger = GetQuietLogger(benchmarkCase.Config, logger); var executeResult = toolchain.Executor.Execute( new ExecuteParameters( buildResult, benchmarkCase, benchmarkId, - logger, + quietLogger, resolver, launchIndex, diagnoser)); @@ -518,11 +522,11 @@ private static ExecuteResult RunExecute(ILogger logger, BenchmarkCase benchmarkC { if (executeResult.ExitCode is int exitCode) { - logger.WriteLineInfo($"// Benchmark Process {executeResult.ProcessId} has exited with code {exitCode}."); + quietLogger.WriteLineInfo($"// Benchmark Process {executeResult.ProcessId} has exited with code {exitCode}."); } else { - logger.WriteLineInfo($"// Benchmark Process {executeResult.ProcessId} failed to exit."); + quietLogger.WriteLineInfo($"// Benchmark Process {executeResult.ProcessId} failed to exit."); } } @@ -678,5 +682,9 @@ private static void PrintValidationErrors(ILogger logger, IEnumerable !config.Options.IsSet(ConfigOptions.QuietMode) ? logger : NullLogger.Instance; + } } \ No newline at end of file