From 2c95efe8daa01f8c2772774ab793ddb118ed7326 Mon Sep 17 00:00:00 2001 From: filzrev <103790468+filzrev@users.noreply.github.com> Date: Mon, 5 Jan 2026 12:48:44 +0900 Subject: [PATCH] chore: add analyzer debug settings and sandbox project --- BenchmarkDotNet.slnx | 1 + samples/BenchmarkDotNet.Samples.Sandbox.slnf | 11 ++ .../.runsettings | 9 ++ .../BenchmarkDotNet.Samples.Sandbox.csproj | 38 ++++++ .../Configs/BaseBenchmarkConfig.cs | 121 ++++++++++++++++++ .../Configs/DebugBenchmarkConfig.cs | 28 ++++ .../Configs/DebugInProcessBenchmarkConfig.cs | 40 ++++++ .../Configs/DefaultBenchmarkConfig.cs | 22 ++++ .../TargetFrameworksBenchmarkConfig.cs | 50 ++++++++ .../ExtensionMethods/SummariesExtensions.cs | 23 ++++ .../Filters/TargetFrameworkFilter.cs | 47 +++++++ .../Helpers/AssemblyConfigProvider.cs | 35 +++++ .../Benchmarks/DefaultBenchmarks.cs | 42 ++++++ .../Constants.cs | 25 ++++ .../Program.cs | 51 ++++++++ .../Properties/PropertyInfo.cs | 3 + .../Properties/launchSettings.json | 37 ++++++ .../BenchmarkDotNet.Analyzers.csproj | 2 + .../Properties/launchSettings.json | 8 ++ .../Fixtures/AnalyzerTestFixture.cs | 1 + 20 files changed, 594 insertions(+) create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox.slnf create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/.runsettings create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet.Samples.Sandbox.csproj create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/BaseBenchmarkConfig.cs create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/DebugBenchmarkConfig.cs create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/DebugInProcessBenchmarkConfig.cs create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/DefaultBenchmarkConfig.cs create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/TargetFrameworksBenchmarkConfig.cs create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/ExtensionMethods/SummariesExtensions.cs create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Filters/TargetFrameworkFilter.cs create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Helpers/AssemblyConfigProvider.cs create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/Benchmarks/DefaultBenchmarks.cs create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/Constants.cs create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/Program.cs create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/Properties/PropertyInfo.cs create mode 100644 samples/BenchmarkDotNet.Samples.Sandbox/Properties/launchSettings.json create mode 100644 src/BenchmarkDotNet.Analyzers/Properties/launchSettings.json diff --git a/BenchmarkDotNet.slnx b/BenchmarkDotNet.slnx index 1d2b3755ad..ffadc5d113 100644 --- a/BenchmarkDotNet.slnx +++ b/BenchmarkDotNet.slnx @@ -6,6 +6,7 @@ + diff --git a/samples/BenchmarkDotNet.Samples.Sandbox.slnf b/samples/BenchmarkDotNet.Samples.Sandbox.slnf new file mode 100644 index 0000000000..f8357fd4a2 --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox.slnf @@ -0,0 +1,11 @@ +{ + "solution": { + "path": "..\\BenchmarkDotNet.slnx", + "projects": [ + "samples\\BenchmarkDotNet.Samples.Sandbox\\BenchmarkDotNet.Samples.Sandbox.csproj", + "src\\BenchmarkDotNet.Analyzers\\BenchmarkDotNet.Analyzers.csproj", + "src\\BenchmarkDotNet.TestAdapter\\BenchmarkDotNet.TestAdapter.csproj", + "src\\BenchmarkDotNet\\BenchmarkDotNet.csproj" + ] + } +} diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/.runsettings b/samples/BenchmarkDotNet.Samples.Sandbox/.runsettings new file mode 100644 index 0000000000..4c125cf1f5 --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/.runsettings @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet.Samples.Sandbox.csproj b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet.Samples.Sandbox.csproj new file mode 100644 index 0000000000..b6b9b4ac31 --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet.Samples.Sandbox.csproj @@ -0,0 +1,38 @@ + + + + + Exe + net8.0;net9.0;net10.0 + enable + + + + $(TargetFrameworks);net48 + + + + + false + + false + + $(MSBuildProjectDirectory)\.runsettings + + + + + + Analyzer + false + + + + + + + + + + + diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/BaseBenchmarkConfig.cs b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/BaseBenchmarkConfig.cs new file mode 100644 index 0000000000..43925d9bfd --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/BaseBenchmarkConfig.cs @@ -0,0 +1,121 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Columns; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Exporters; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Loggers; +using BenchmarkDotNet.Order; +using BenchmarkDotNet.Reports; +using Perfolizer.Horology; + +namespace BenchmarkDotNet; + +public class BaseBenchmarkConfig : ManualConfig +{ + public BaseBenchmarkConfig() + { + WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(40)); // Default: 20 chars + WithBuildTimeout(TimeSpan.FromMinutes(10)); // Default: 120 seconds + + WithOrderer(new DefaultOrderer()); + WithUnionRule(ConfigUnionRule.Union); + WithArtifactsPath(DefaultConfig.Instance.ArtifactsPath!); + +#if DEBUG + // Allow benchmarks for debug build. + WithOptions(ConfigOptions.DisableOptimizationsValidator); +#endif + + // Enable following settings for debugging + // WithOptions(ConfigOptions.StopOnFirstError); + // WithOptions(ConfigOptions.KeepBenchmarkFiles); + // WithOptions(ConfigOptions.GenerateMSBuildBinLog); + } + + // Use ShortRun based settings (LaunchCount=1 IterationCount=3 WarmupCount = 3) + // And use RecommendedConfig setting that used by `dotnet/performance` repository. + // https://github.com/dotnet/performance/blob/main/src/harness/BenchmarkDotNet.Extensions/RecommendedConfig.cs + protected virtual Job GetBaseJobConfig() => + Job.Default + .WithLaunchCount(1) + .WithWarmupCount(3) + .WithIterationTime(TimeInterval.FromMilliseconds(250)) // Default: 500 [ms] + .WithMinIterationCount(15) // Default: 15 + .WithMaxIterationCount(20); // Default: 100 + + /// + /// Add configurations. + /// + protected void AddConfigurations() + { + AddAnalyzers(); + AddColumnHidingRules(); + AddColumnProviders(); + AddDiagnosers(); + AddEventProcessors(); + AddExporters(); + AddFilters(); + AddHardwareCounters(); + AddLoggers(); + AddLogicalGroupRules(); + AddValidators(); + } + + protected virtual void AddAnalyzers() + { + AddAnalyser(DefaultConfig.Instance.GetAnalysers().ToArray()); + } + + protected virtual void AddColumnHidingRules() + { + } + + protected virtual void AddColumnProviders() + { + AddColumnProvider(DefaultColumnProviders.Instance); + } + + protected virtual void AddDiagnosers() + { + AddDiagnoser(MemoryDiagnoser.Default); + AddDiagnoser(new ExceptionDiagnoser(new ExceptionDiagnoserConfig(displayExceptionsIfZeroValue: false))); + +#if NETCOREAPP3_0_OR_GREATER + AddDiagnoser(new ThreadingDiagnoser(new ThreadingDiagnoserConfig(displayCompletedWorkItemCountWhenZero: false, displayLockContentionWhenZero: false))); +#endif + } + + protected virtual void AddExporters() + { + // Use ConsoleMarkdownExporter to disable group higligting with `**`. + AddExporter(MarkdownExporter.Console); + } + + protected virtual void AddEventProcessors() + { + } + + protected virtual void AddFilters() + { + AddFilter(TargetFrameworkFilter.Instance); + } + + protected virtual void AddHardwareCounters() + { + } + + protected virtual void AddLoggers() + { + AddLogger(ConsoleLogger.Default); + } + + protected virtual void AddLogicalGroupRules() + { + } + + protected virtual void AddValidators() + { + AddValidator(DefaultConfig.Instance.GetValidators().ToArray()); + } +} diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/DebugBenchmarkConfig.cs b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/DebugBenchmarkConfig.cs new file mode 100644 index 0000000000..7b0669687c --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/DebugBenchmarkConfig.cs @@ -0,0 +1,28 @@ +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Toolchains.InProcess.Emit; +using System.Runtime.InteropServices; + +namespace BenchmarkDotNet; + +public class DebugBenchmarkConfig : BaseBenchmarkConfig +{ + public DebugBenchmarkConfig() + { + // Configure base job config + var baseJobConfig = GetBaseJobConfig(); + + // Add benchmark job. + AddJob(baseJobConfig.WithCustomBuildConfiguration("Debug") + .WithWarmupCount(1) + .WithStrategy(RunStrategy.Monitoring) + .WithId($"Debug({RuntimeInformation.FrameworkDescription})")); + + // Set DebugConfig comatible option + WithOptions(ConfigOptions.KeepBenchmarkFiles); + + // Configure additional settings. + AddConfigurations(); + } +} diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/DebugInProcessBenchmarkConfig.cs b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/DebugInProcessBenchmarkConfig.cs new file mode 100644 index 0000000000..3447788af0 --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/DebugInProcessBenchmarkConfig.cs @@ -0,0 +1,40 @@ +using BenchmarkDotNet.Analysers; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Toolchains.InProcess.Emit; +using System.Runtime.InteropServices; + +namespace BenchmarkDotNet; + +public class DebugInProcessBenchmarkConfig : BaseBenchmarkConfig +{ + public DebugInProcessBenchmarkConfig() : base() + { + // Configure base job config + var baseJobConfig = GetBaseJobConfig(); + + // Add benchmark job. + AddJob(baseJobConfig.WithToolchain(InProcessEmitToolchain.Default) + .WithWarmupCount(1) + .WithStrategy(RunStrategy.Monitoring) + .WithId($"DebugInProcess({RuntimeInformation.FrameworkDescription})")); + + // Set DebugConfig comatible option + WithOptions(ConfigOptions.KeepBenchmarkFiles); + + // Configure additional settings. + AddConfigurations(); + } + + protected override void AddAnalyzers() + { + // Exclude MinIterationTimeAnalyser that cause warning when using RunStrategy.Monitoring. + var analyzers = DefaultConfig.Instance + .GetAnalysers() + .Where(x => x is not MinIterationTimeAnalyser) + .ToArray(); + + AddAnalyser(analyzers); + } +} diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/DefaultBenchmarkConfig.cs b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/DefaultBenchmarkConfig.cs new file mode 100644 index 0000000000..60246b8b98 --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/DefaultBenchmarkConfig.cs @@ -0,0 +1,22 @@ +using BenchmarkDotNet.Jobs; +using System.Runtime.InteropServices; + +namespace BenchmarkDotNet; + +public class DefaultBenchmarkConfig : BaseBenchmarkConfig +{ + public DefaultBenchmarkConfig() : base() + { + // Configure base job config + var baseJobConfig = GetBaseJobConfig(); + + // Create benchmark job. + var job = baseJobConfig.WithId($"Default({RuntimeInformation.FrameworkDescription})"); + + // Add job. + AddJob(job); + + // Configure additional settings. + AddConfigurations(); + } +} diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/TargetFrameworksBenchmarkConfig.cs b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/TargetFrameworksBenchmarkConfig.cs new file mode 100644 index 0000000000..32711dcaa0 --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Configs/TargetFrameworksBenchmarkConfig.cs @@ -0,0 +1,50 @@ +using BenchmarkDotNet.Analysers; +using BenchmarkDotNet.Columns; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Toolchains.CsProj; + +namespace BenchmarkDotNet; + +/// +/// BenchmarkConfig that run benchmarks for multiple target frameworks. +/// +public class TargetFrameworksBenchmarkConfig : BaseBenchmarkConfig +{ + /// + /// Initializes a new instance of the class. + /// + public TargetFrameworksBenchmarkConfig() : base() + { + // Configure base job config + var baseJobConfig = GetBaseJobConfig(); + + // Add jobs + AddJob(baseJobConfig.WithToolchain(CsProjCoreToolchain.NetCoreApp80).WithId(".NET 8").AsBaseline()); + AddJob(baseJobConfig.WithToolchain(CsProjCoreToolchain.NetCoreApp90).WithId(".NET 9")); + AddJob(baseJobConfig.WithToolchain(CsProjCoreToolchain.NetCoreApp10_0).WithId(".NET 10")); + + // AddJob(baseJobConfig.WithToolchain(CsProjClassicNetToolchain.Net48).WithId(".NET Framework 4.8")); + + // Configure additional settings. + AddConfigurations(); + } + + protected override void AddLogicalGroupRules() + { + // Grouping benchmarks by method. + // Note: When following conditions are met. BaselineCustomAnalyzer raise warning. See: https://github.com/dotnet/BenchmarkDotNet/issues/2956 + // 1. Job contains Baseline=true + // 2. Benchmark method contains Baseline=true + // 3. Enable grouping with method. + AddLogicalGroupRules( + [ + BenchmarkLogicalGroupRule.ByMethod, + ]); + } + + protected override void AddColumnHidingRules() + { + HideColumns(Column.Toolchain); // Toolchain information are shown at JobId column. + } +} diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/ExtensionMethods/SummariesExtensions.cs b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/ExtensionMethods/SummariesExtensions.cs new file mode 100644 index 0000000000..8be1d0452a --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/ExtensionMethods/SummariesExtensions.cs @@ -0,0 +1,23 @@ +using BenchmarkDotNet.Reports; + +namespace BenchmarkDotNet; + +public static class SummariesExtensions +{ + public static bool HasError(this Summary[] summaries) + { + if (summaries.Length == 0) + { + var hashSet = new HashSet(["--help", "--list", "--info", "--version"]); + + var args = Environment.GetCommandLineArgs(); + return !args.Any(hashSet.Contains); + } + + if (summaries.Any(x => x.HasCriticalValidationErrors)) + return true; + + return summaries.Any(x => x.Reports.Any(r => !r.Success)); + } +} + diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Filters/TargetFrameworkFilter.cs b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Filters/TargetFrameworkFilter.cs new file mode 100644 index 0000000000..53a87300a7 --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Filters/TargetFrameworkFilter.cs @@ -0,0 +1,47 @@ +using BenchmarkDotNet.Filters; +using BenchmarkDotNet.Running; +using BenchmarkDotNet.Samples.Sandbox; +using BenchmarkDotNet.Toolchains.CsProj; +using System.Linq; + +namespace BenchmarkDotNet; + +/// +/// Custom BenchmarkDotNet filter to exclude benchmarks based on target framework category. +/// This filter is required because BenchmarkDotNet don't support conditional benchmarks with `#if` directive. +/// +public partial class TargetFrameworkFilter : IFilter +{ + public static readonly TargetFrameworkFilter Instance = new(); + + private TargetFrameworkFilter() { } + + public virtual bool Predicate(BenchmarkCase benchmarkCase) + { + var toolchain = benchmarkCase.Job.Infrastructure.Toolchain; + if (toolchain == null || toolchain is not CsProjCoreToolchain) + return true; + + var versionText = toolchain.Name.Split(' ').Last(); // Expected `.NET 8.0` format. + if (!Version.TryParse(versionText, out var targetVersion)) + return true; // Return true if failed to resolve target version. + + var categories = benchmarkCase.Descriptor.Categories; + foreach (var category in categories) + { + switch (category) + { + case Categories.Filters.NET8_0_OR_GREATER: + return targetVersion.Major >= 8; + case Categories.Filters.NET9_0_OR_GREATER: + return targetVersion.Major >= 9; + case Categories.Filters.NET10_0_OR_GREATER: + return targetVersion.Major >= 10; + default: + continue; + } + } + + return true; + } +} diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Helpers/AssemblyConfigProvider.cs b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Helpers/AssemblyConfigProvider.cs new file mode 100644 index 0000000000..eca3e3b5b3 --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/BenchmarkDotNet/Helpers/AssemblyConfigProvider.cs @@ -0,0 +1,35 @@ +using BenchmarkDotNet.Configs; + +namespace BenchmarkDotNet; + +/// +/// This class provide assembly level benchmark config. +/// It's required because `Program.cs` and `launchSettings.json` is not used when running on VS TestExplorer. +/// +[AttributeUsage(AttributeTargets.Assembly)] +internal class AssemblyConfigProvider : Attribute, IConfigSource +{ + public static IConfig GetConfig() => config.Value; + + public IConfig Config => config.Value; + + private static readonly Lazy config = new(() => + { + var configKey = Environment.GetEnvironmentVariable(Constants.EnvironmentVariables.BenchmarkDotNetConfig) ?? ""; + + switch (configKey) + { + case "": + case "Default": + return new DefaultBenchmarkConfig(); + case "Debug": + return new DebugBenchmarkConfig(); + case "DebugInProcess": + return new DebugInProcessBenchmarkConfig(); + case "TargetFrameworks": + return new TargetFrameworksBenchmarkConfig(); + default: + throw new InvalidOperationException($"Unknown benchmark config key is specified: {configKey}"); + } + }); +} diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/Benchmarks/DefaultBenchmarks.cs b/samples/BenchmarkDotNet.Samples.Sandbox/Benchmarks/DefaultBenchmarks.cs new file mode 100644 index 0000000000..555b3d5367 --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/Benchmarks/DefaultBenchmarks.cs @@ -0,0 +1,42 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; + +namespace BenchmarkDotNet.Samples.Sandbox; + +public class DefaultBenchmarks +{ + private readonly Consumer Consumer = new(); + + // [Params(1_000_000)] + public int N { get; set; } = 1_000_000; + + private readonly IEnumerable EnumerableDataSource; + private readonly int[] ArrayDataSource; + + public DefaultBenchmarks() + { + var rand = new Random(0); + var source = Enumerable.Range(1, N).Select(x => rand.Next()); + + EnumerableDataSource = source; + ArrayDataSource = EnumerableDataSource.ToArray(); + } + + [Benchmark(Baseline = true)] + public void Benchmark01() + { + foreach (var i in EnumerableDataSource.OrderBy(x => x)) + { + Consumer.Consume(i); + } + } + + [Benchmark] + public void Benchmark02() + { + foreach (var i in ArrayDataSource.OrderBy(x => x)) + { + Consumer.Consume(i); + } + } +} diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/Constants.cs b/samples/BenchmarkDotNet.Samples.Sandbox/Constants.cs new file mode 100644 index 0000000000..c19240c275 --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/Constants.cs @@ -0,0 +1,25 @@ +using BenchmarkDotNet.Toolchains; +using BenchmarkDotNet.Toolchains.CsProj; + +namespace BenchmarkDotNet; + +internal class Constants +{ + public static readonly IToolchain DefaultToolchain = CsProjCoreToolchain.NetCoreApp10_0; + + public class EnvironmentVariables + { + public const string BenchmarkDotNetConfig = "BENCHMARKDOTNET_CONFIG"; + } +} + +internal class Categories +{ + // Categories that is used to filter benchmarks. + public static class Filters + { + public const string NET8_0_OR_GREATER = "NET8_0_OR_GREATER"; + public const string NET9_0_OR_GREATER = "NET9_0_OR_GREATER"; + public const string NET10_0_OR_GREATER = "NET10_0_OR_GREATER"; + } +} diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/Program.cs b/samples/BenchmarkDotNet.Samples.Sandbox/Program.cs new file mode 100644 index 0000000000..1f64e1aa8b --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/Program.cs @@ -0,0 +1,51 @@ +using BenchmarkDotNet.Columns; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Exporters; +using BenchmarkDotNet.Loggers; +using BenchmarkDotNet.Running; + +namespace BenchmarkDotNet.Samples.Sandbox; + +internal class Program +{ + public static int Main(string[] args) + { + var logger = ConsoleLogger.Default; +#if DEBUG + logger.WriteLineWarning("Benchmark is executed with DEBUG configuration."); + logger.WriteLine(); +#endif + + if (args.Length != 0) + logger.WriteLine($"Start benchmarks with args: {string.Join(" ", args)}"); + + try + { + // Get benchmark config + var config = AssemblyConfigProvider.GetConfig(); + logger.WriteLine($"Selected benchmark config: {config.GetType().Name}"); + logger.WriteLine(); + + // Run benchmarks + var summaries = BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly) + .Run(args, config) + .ToArray(); + + // Check benchmark results. + if (summaries.HasError()) + { + logger.WriteLine(); + logger.WriteLineError("Failed to run benchmarks."); + return 1; + } + + return 0; + } + catch (Exception ex) + { + logger.WriteLineError(ex.ToString()); + return 1; + } + } +} diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/Properties/PropertyInfo.cs b/samples/BenchmarkDotNet.Samples.Sandbox/Properties/PropertyInfo.cs new file mode 100644 index 0000000000..0254732fbf --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/Properties/PropertyInfo.cs @@ -0,0 +1,3 @@ +using BenchmarkDotNet; + +[assembly: AssemblyConfigProvider] diff --git a/samples/BenchmarkDotNet.Samples.Sandbox/Properties/launchSettings.json b/samples/BenchmarkDotNet.Samples.Sandbox/Properties/launchSettings.json new file mode 100644 index 0000000000..7bf430c88a --- /dev/null +++ b/samples/BenchmarkDotNet.Samples.Sandbox/Properties/launchSettings.json @@ -0,0 +1,37 @@ +{ + "profiles": { + "Default": { + "commandName": "Project", + "commandLineArgs": "--filter *DefaultBenchmarks*", + "environmentVariables": { + } + }, + "Debug": { + "commandName": "Project", + "commandLineArgs": "--filter *DefaultBenchmarks*", + "environmentVariables": { + "BENCHMARKDOTNET_CONFIG": "Debug" + } + }, + "DebugInProcess": { + "commandName": "Project", + "commandLineArgs": "--filter *DefaultBenchmarks*", + "environmentVariables": { + "BENCHMARKDOTNET_CONFIG": "DebugInProcess" + } + }, + "TargetFrameworks": { + "commandName": "Project", + "commandLineArgs": "--filter *DefaultBenchmarks*", + "environmentVariables": { + "BENCHMARKDOTNET_CONFIG": "TargetFrameworks" + } + }, + "Help": { + "commandName": "Project", + "commandLineArgs": "--help", + "environmentVariables": { + } + } + } +} diff --git a/src/BenchmarkDotNet.Analyzers/BenchmarkDotNet.Analyzers.csproj b/src/BenchmarkDotNet.Analyzers/BenchmarkDotNet.Analyzers.csproj index 647308d606..1db648deb0 100644 --- a/src/BenchmarkDotNet.Analyzers/BenchmarkDotNet.Analyzers.csproj +++ b/src/BenchmarkDotNet.Analyzers/BenchmarkDotNet.Analyzers.csproj @@ -5,6 +5,8 @@ false BenchmarkDotNet.Analyzers + cs + true true $(NoWarn);CS1591 diff --git a/src/BenchmarkDotNet.Analyzers/Properties/launchSettings.json b/src/BenchmarkDotNet.Analyzers/Properties/launchSettings.json new file mode 100644 index 0000000000..84a45213e0 --- /dev/null +++ b/src/BenchmarkDotNet.Analyzers/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "Debug": { + "commandName": "DebugRoslynComponent", + "targetProject": "..\\..\\samples\\BenchmarkDotNet.Samples.Sandbox\\BenchmarkDotNet.Samples.Sandbox.csproj" + } + } +} diff --git a/tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/AnalyzerTestFixture.cs b/tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/AnalyzerTestFixture.cs index 7b3cd39fe6..8114f9a6ce 100644 --- a/tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/AnalyzerTestFixture.cs +++ b/tests/BenchmarkDotNet.Analyzers.Tests/Fixtures/AnalyzerTestFixture.cs @@ -5,6 +5,7 @@ using Microsoft.CodeAnalysis.Testing; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks;