with one click
performance-benchmark
Generate and run ad hoc performance benchmarks to validate code changes. Use this when asked to benchmark, profile, or validate the performance impact of a code change in dotnet/runtime.
Menu
Generate and run ad hoc performance benchmarks to validate code changes. Use this when asked to benchmark, profile, or validate the performance impact of a code change in dotnet/runtime.
| name | performance-benchmark |
| description | Generate and run ad hoc performance benchmarks to validate code changes. Use this when asked to benchmark, profile, or validate the performance impact of a code change in dotnet/runtime. |
When you need to validate the performance impact of a code change, follow this process to write a BenchmarkDotNet benchmark and trigger @EgorBot to run it. The bot will notify you when results are ready, so don't wait for them.
Create a BenchmarkDotNet benchmark that tests the specific operation being changed. Follow these guidelines:
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(Bench).Assembly).Run(args);
public class Bench
{
// Add setup/cleanup if needed
[GlobalSetup]
public void Setup()
{
// Initialize test data
}
[Benchmark]
public void MyOperation()
{
// Test the operation
}
}
For comprehensive guidance, see the Microbenchmark Design Guidelines.
Key principles:
[GlobalSetup]: Separate setup logic from the measured code to avoid measuring allocation/initialization overhead[DisassemblyDiagnoser]: It causes crashes on Linux. Use --envvars DOTNET_JitDisasm:MethodName insteadpublic, not sealed, not static, and must be a class (not struct)using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(Bench).Assembly).Run(args);
[MemoryDiagnoser]
public class Bench
{
private string _testString = default!;
[Params(10, 100, 1000)]
public int Length { get; set; }
[GlobalSetup]
public void Setup()
{
_testString = new string('a', Length);
}
[Benchmark]
public int StringOperation()
{
return _testString.IndexOf('z');
}
}
using System.Linq;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(Bench).Assembly).Run(args);
[MemoryDiagnoser]
public class Bench
{
private int[] _array = default!;
private List<int> _list = default!;
[Params(100, 1000, 10000)]
public int Count { get; set; }
[GlobalSetup]
public void Setup()
{
_array = Enumerable.Range(0, Count).ToArray();
_list = _array.ToList();
}
[Benchmark]
public bool AnyArray() => _array.Any();
[Benchmark]
public bool AnyList() => _list.Any();
[Benchmark]
public int SumArray() => _array.Sum();
[Benchmark]
public int SumList() => _list.Sum();
}
Post a comment on the PR to trigger EgorBot with your benchmark. The general format is:
📝 AI-generated content disclosure: When posting benchmark comments to GitHub under a user's credentials — i.e., the account is not a dedicated "copilot" or "bot" account/app (e.g.,
github-actions[bot],copilot) — you MUST include a concise, visible note (e.g. a> [!NOTE]alert) at the bottom of the content indicating the content was AI/Copilot-generated. Skip this if the user explicitly asks you to omit it.
@EgorBot [targets] [options] [BenchmarkDotNet args]
// Your benchmark code here
Note: When using @EgorBot, follow these formatting rules:
- The @EgorBot command must not be inside the code block.
- Only the benchmark code should be inside the code block.
- Do not place any additional text between the @EgorBot command line and the code block, as EgorBot will treat it as additional command arguments.
-linux_amd-linux_intel-windows_amd-windows_intel-linux_arm64-osx_arm64 (baremetal, feel free to always include it)The most common combination is -linux_amd -osx_arm64. Do not include more than 4 targets.
Use -profiler when absolutely necessary along with -linux_arm64 and/or -linux_amd to include perf profiling and disassembly in the results.
To benchmark the current PR changes against the base branch:
@EgorBot -linux_amd -osx_arm64
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(Bench).Assembly).Run(args);
[MemoryDiagnoser]
public class Bench
{
[Benchmark]
public int MyOperation()
{
// Your benchmark code
return 42;
}
}
dotnet/runtime and EgorBot/runtime-utilsCreate prototype-backed API proposals for dotnet/runtime. Use when asked to draft an API proposal, write an api-suggestion issue, refine a vague API idea into a complete proposal, or improve a proposal marked api-needs-work. Covers the full pipeline from research through prototyping, ref source generation, and publishing. DO NOT USE FOR bug fixes, code review, performance benchmarking, or internal API changes that don't affect public surface area.
Review code changes in dotnet/runtime for correctness, performance, and consistency with project conventions. Use when reviewing PRs or code changes.
Analyze a dotnet/runtime PR's CI failures, skip failures already known to Build Analysis, find matching Known Build Errors, and create or draft new KBEs for the remaining failures. Supports dry-run output to local markdown files instead of creating GitHub issues.
Triage Fuzzlyn CI runs.
Generate breaking change documentation for merged dotnet/runtime PRs. USE FOR: creating breaking change docs, "document this breaking change", "write breaking change issue for PR #NNNNN", processing PRs labeled needs-breaking-change-doc-created. DO NOT USE FOR: general code review (use code-review skill), bug fixes, API proposals (use api-proposal skill).
Domain knowledge for triaging and fixing .NET failures on Apple mobile (iOS, tvOS, MacCatalyst) and Android. Use when runtime-extra-platforms or mobile CI is failing, when investigating iOS, tvOS, MacCatalyst, iossimulator, tvossimulator, or Android build/test failures, or when a change touches mobile pipeline YAML, AppleAppBuilder/AndroidAppBuilder, code signing, provisioning, simulator/emulator startup, platform conditionals, or NativeAOT-on-mobile behavior. Covers failure triage (infrastructure vs code), CI pipeline structure, platform-specific code paths, and NativeAOT compilation on mobile.