A powerful CLI tool for automatically generating BenchmarkDotNet projects and performance reports for .NET solutions.
- Unit Benchmark Generation: Automatically creates benchmarks for every public class and method in your solution
- E2E Benchmark Generation: Creates end-to-end benchmarks for Web APIs (using WebApplicationFactory) and Console applications
- SignalR E2E Detection: Automatically discovers SignalR hubs and generates full message round-trip benchmarks
- Benchmark Results Reporting: Run benchmarks and generate comprehensive markdown reports with performance metrics, throughput analysis, and quality insights
- Dual Reports: Technical report for developers and product owner report for stakeholders
- File-Per-Command Architecture: Uses System.CommandLine with proper separation of concerns
- Microsoft Extensions Integration: Built with DI, Configuration, Logging, and Options pattern
- BenchmarkDotNet Integration: Generates projects ready to run with BenchmarkDotNet
Install as a global .NET tool:
dotnet tool install -g QuinntyneBrown.Benchmark.CliUpdate to the latest version:
dotnet tool update -g QuinntyneBrown.Benchmark.Clibn generate <path-to-solution>This generates both unit and E2E benchmark projects for your solution. Accepts both .sln and .slnx solution files.
bn run-and-report <path-to-solution>Specify a custom output path for the report:
bn run-and-report <path-to-solution> --output ./reports/benchmark-results.mdThis command will:
- Generate unit and E2E benchmark projects
- Run all benchmarks (this may take several minutes)
- Collect and analyze results
- Generate two comprehensive markdown reports:
- BenchmarkReport.md — detailed metrics for developers
- ProductOwnerReport.md — health summary for stakeholders
The tool creates two benchmark projects in your solution directory:
- {SolutionName}.UnitBenchmarks: Contains benchmarks for all public methods in your classes
- {SolutionName}.E2EBenchmarks: Contains end-to-end benchmarks for Web APIs and Console applications
If you prefer to run benchmarks manually without generating reports:
cd {SolutionName}.UnitBenchmarks
dotnet run -c Release
cd {SolutionName}.E2EBenchmarks
dotnet run -c Release- Getting Started — installation, prerequisites, and quick start
- Command Reference — full CLI reference for all commands
- Interpreting Reports — how to read metrics, categories, and verdicts
- Architecture — how the tool works internally
├── src/
│ ├── Benchmark.Cli/ # CLI application with System.CommandLine
│ │ ├── Commands/ # Command implementations
│ │ ├── Options/ # Configuration options
│ │ └── Program.cs # Entry point with DI setup
│ └── Benchmark.Core/ # Core library with business logic
│ ├── Models/ # Domain models
│ ├── Services/ # Service implementations
│ └── Generators/ # Code generation utilities
├── docs/ # User guides and reference documentation
└── Benchmark.sln
- System.CommandLine: Modern command-line parsing
- Microsoft.Extensions.DependencyInjection: Dependency injection
- Microsoft.Extensions.Logging: Structured logging
- Microsoft.Extensions.Configuration: Configuration management
- Microsoft.Extensions.Options: Options pattern
- Roslyn: Solution and code analysis
- BenchmarkDotNet: Performance benchmarking
- .NET 9.0 or later
- A valid .NET solution file (.sln or .slnx)
[MemoryDiagnoser]
public class MyServiceBenchmarks
{
private MyService? _testSubject;
[GlobalSetup]
public void Initialize()
{
_testSubject = new MyService();
}
[Benchmark]
public void Measure_ProcessData()
{
_testSubject!.ProcessData("sample");
}
}[MemoryDiagnoser]
public class MyApiE2EBenchmarks
{
private HttpClient? _httpClient;
[GlobalSetup]
public void Initialize()
{
// Configure with WebApplicationFactory
}
[Benchmark]
public async Task MeasureApiEndpoint()
{
var result = await _httpClient!.GetAsync("/api/endpoint");
result.EnsureSuccessStatusCode();
}
}MIT