Install
$ agentstack add skill-jeremykuhne-agent-skills-performance-testing ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Performance testing with BenchmarkDotNet
If overlay.md exists beside this file, read it before acting; it contains repository-specific bindings. This core remains usable without it.
This skill covers authoring and running BenchmarkDotNet benchmarks in a multi-targeted .NET library's perf project (.perf by convention), and - just as important - turning a user's vague, outcome-shaped performance question into a concrete measurement and a useful answer.
A consuming repository wires the concrete project name, target frameworks, cross-skill links, and profiling tooling in its overlay. This core uses .perf for the perf project and ` for a target-framework moniker; the overlay supplies the real names. The two framework monikers this skill names directly - modern .NET (net10.0 or whatever the repo's current version is) and .NET Framework (net481`) - are the common multi-targeting pair; a single-target repo simply ignores the second.
Note: code in a Framework-only source tree (the Framework/ subtree by convention, excluded from the modern build) compiles only for the .NET Framework target. References to those types from a benchmark must be guarded with #if NETFRAMEWORK.
Starting from a user's question
Users ask outcome questions - "how long does this take?", "how much memory does this use?", "where is the time going?", "help me make this faster?" - not tooling commands. They will not pick a scenario, write a benchmark, or capture a trace on their own; translating the question into a measurement and leading them through it is the job. Before reaching for the mechanics below, read [interpreting-requests.md](interpreting-requests.md): it maps each kind of question to the right workflow, says which clarifications to ask (and which to answer yourself from the code), walks the "make X faster" journey end to end, and lists the follow-ups to offer once a result is in hand. The rest of this skill is the how; that page is the what to measure and why.
Related skills (a consuming repo links the ones it vendors in its overlay):
- A trace-analyzer skill - the profiler this skill drives to find the hot
method or source line. The overlay names it and the concrete profiling page.
- A framework-JIT-optimization skill - decisions about specialization,
unrolling, and BCL-delegation on the older Framework JIT that the benchmarks here exist to validate.
- A scratch-buffer-strategy skill - choosing between zeroed
stackalloc,
[SkipLocalsInit], a stack-with-pool-fallback buffer, and an ArrayPool rental; several benchmarks exist to validate those crossovers.
- A pre-pr-self-review skill - which requires a benchmark (or an explicit
"not measured" note) for any perf claim that drives a Framework-only code change.
The rules that always apply
Five rules cover most benchmark work; the sub-pages hold the rest.
- Pass
-f. A multi-targeted perf project makesdotnet runfail
without an explicit target framework (e.g. -f net10.0 or -f net481).
-c Releaseis mandatory. Debug runs are not representative.[MemoryDiagnoser]on every class. It adds theAllocatedcolumn, which
is usually the point.
- Every
[Benchmark]method returns a value derived from the work, never
void - otherwise dead-code elimination wipes the body and the numbers are meaningless. See [authoring.md](authoring.md).
- Run both TFMs for any code that compiles for both. Results diverge: the
modern runtime has vectorized BCL APIs the older Framework runtime lacks.
# The canonical run, one TFM. Repeat with the other -f .
dotnet run -c Release -f --project .perf -- --filter *MyBenchmark*
Workflow checklist for a new benchmark
- Add a
.csfile under the perf project with apublicclass in the
perf namespace. See [authoring.md](authoring.md) for layout, globals, and attributes.
- Decorate the class with
[MemoryDiagnoser]. - Add
[Benchmark(Baseline = true)]to the reference implementation and
[Benchmark] to each variant.
- Make every benchmark method return a value derived from the work, never
void.
- Avoid helper-method indirection between the benchmark and the
system-under-test. If overload resolution forces it, temporarily rename one overload in source while measuring, then revert.
- Build Release:
dotnet build -c Release .perf. - Smoke-test with
--job short --filter **on each target framework
individually. See [running.md](running.md).
- Run the full benchmark on both target frameworks (drop
--job short). - Inspect
AllocatedandRatiocolumns; copy the Markdown report into the PR.
See [interpreting-results.md](interpreting-results.md).
- If one method dominates and you need to know which - or which line inside
it - profile it. See your repo's profiling overlay (the trace-analyzer skill).
When the change is driven by a profile, follow the before/after discipline in [interpreting-results.md](interpreting-results.md) (baseline both TFMs, re-run both, keep full rows, confirm the targeted frame moved).
Codegen-level optimization rules
For decisions about how to write a hot path - whether to specialize a generic for primitives, choose between scalar/unrolled forms, defer to BCL primitives like IndexOf / SequenceEqual, or interpret a Framework-vs-modern divergence - see the framework-JIT-optimization skill. That skill is the right entry point for "this loop is slow on the older Framework JIT, what should I try?" questions, while this one is about authoring and running the benchmarks themselves.
To see why a result is what it is - the C# lowering, the IL, or the JIT asm behind a number - see [reading-codegen.md](reading-codegen.md). It covers sharplab, BenchmarkDotNet's [DisassemblyDiagnoser] / [HardwareCounters], the DOTNET_JitDisasm* knobs, and the tiering/PGO traps that bite codegen inspection.
Sub-pages
- [interpreting-requests.md](interpreting-requests.md) - turning a user's
outcome question ("how long?", "how much memory?", "where's the time?", "make it faster") into a scenario, a measurement, an answer in their words, and the next follow-up to offer. Start here when the request is a question, not a task.
- [authoring.md](authoring.md) - file/class layout, the imported globals, the
required and optional attributes, and what a benchmark method must do.
- [running.md](running.md) - the
-frequirement, filtering to a class or
method, the interactive picker, and useful switches.
- [interpreting-results.md](interpreting-results.md) - before/after discipline on
both TFMs and reading the memory columns.
- [reading-codegen.md](reading-codegen.md) - seeing the C# lowering, IL, and JIT
asm behind a number: sharplab, [DisassemblyDiagnoser], [HardwareCounters], the DOTNET_JitDisasm* knobs, and the tiering/PGO inspection traps.
Profiling a benchmark down to the hot method or source line is a repo-specific page supplied by the overlay (it drives the repo's trace analyzer), not part of this core.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: JeremyKuhne
- Source: JeremyKuhne/agent-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.