Install
$ agentstack add skill-jeremykuhne-agent-skills-framework-jit-optimization ✓ 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
.NET Framework 4.8.1 JIT optimization
If overlay.md exists beside this file, read it before acting; it contains repository-specific bindings. This core remains usable without it.
A multi-targeted library targets net481 in addition to modern .NET. Code in the Framework-only source tree (the Framework/ subtree by convention, excluded from the modern build) only ever runs on the older RyuJIT. Treat net481 as a separate optimization target with its own rules.
This skill captures decisions distilled from real BenchmarkDotNet experiments in the repo's perf project (.perf by convention). The deep span-walking field manual is bundled alongside this skill in [references/framework-span-performance.md](references/framework-span-performance.md).
Always validate with the performance-testing skill workflow before committing a change, and run the pre-pr-self-review checklist before opening a PR - in particular its framework-correctness items (allocation-free over raw speed; perf claims must name the JIT and be measured) apply directly to changes guided by this skill.
For the broader "how do I polyfill API X for net472?" question (which packages to prefer, when to hand-roll), see the polyfill-dotnet-api skill. This skill picks up after that decision is already made and the polyfill lives in the Framework-only tree.
For choosing how a hot path gets its scratch buffer (zeroed stackalloc vs [SkipLocalsInit] vs a stack-with-pool-fallback buffer vs an ArrayPool rental, and the net481/net10 size crossovers), see the scratch-buffer-strategy skill.
The net481 rules below have two companions. What the modern target enables that net481 does not (vectorization, hardware intrinsics, struct-generic kernels, and the JIT-friendly shapes you should not hand-tune away) is in [modern-net.md](modern-net.md). The codegen fundamentals that hold on both targets (arithmetic and branchless lowering, uint-for-non-negative, struct layout, zero-allocation static data, hot-path allocation anti-patterns) are in [cross-tfm-codegen.md](cross-tfm-codegen.md).
A consuming repository wires the concrete cross-skill links and source-tree paths in its overlay.
What is and isn't available on net481
- No auto-vectorization. The BCL
MemoryExtensionsmethods on net481 ship with
System.Memory. They are hand-tuned scalar / integer-stride implementations - they do not use SIMD.
- No
System.Runtime.Intrinsics.Vector128/Vector256/Vector512,
Sse2.CompareEqual, Avx2.MoveMask are .NET 5+. Not available here.
- No tiered JIT or PGO. What you write is what gets compiled, once.
VectorfromSystem.Numerics.Vectorstechnically exists but does not
auto-vectorize equality-replace loops on the older JIT, and per-load/store overhead loses to a plain unrolled scalar loop at typical sizes.
- No source-level loop alignment controls.
"Integer-stride" means routines like IndexOf and SequenceEqual internally process multiple elements per loop step (e.g. compare a ulong chunk that spans 4 chars or 8 bytes) rather than one element at a time. This is not vectorization - just careful scalar code - but it still substantially beats a naive per-element loop for whole-buffer primitives.
Practical consequence: do not assume "the BCL is vectorized so my generic code is fine." On net481 a hand-written specialized loop frequently beats the BCL by 2-3× for full-scan workloads.
Decision flow for a new framework-only fast path
- Start with the simplest possible scalar loop and measure it as the baseline.
Capture the baseline on both net10.0 and net481 before editing, and keep the full BenchmarkDotNet rows (Mean/Error/StdDev/Allocated), not a one-line summary - see the before/after discipline in the performance-testing skill. EventPipe line profiling is net10-only, but every change still has to be re-measured on net481 overall.
- Decide whether to specialize. See [specialization.md](specialization.md) for the
typeof(T) pattern and primitive equivalence classes.
- Decide whether to defer to a BCL primitive. See
[bcl-tradeoffs.md](bcl-tradeoffs.md) for the visit-most-vs-skip-runs rule.
- If specializing, add
[MethodImpl(MethodImplOptions.AggressiveInlining)]on the
generic entry point. The net481 JIT's default heuristics are conservative; small specialized loops often will not inline without it.
- If the loop is the hot path, unroll by 4 with indexed reads + bulk pointer
increment. See [unrolling.md](unrolling.md) for the right form (and the wrong ones).
- Stop there. Do not pursue SIMD, SWAR, or branchless tricks without data
showing they win - in practice they regress more often than they help. See [antipatterns.md](antipatterns.md).
- Run the same benchmark on
net10.0to confirm you have not regressed the
modern path. If a specialization is harmful on net10 (because the BCL is actually vectorized there), guard it with #if NETFRAMEWORK so only net481 gets the loop.
- Report both TFMs' before/after tables together, and confirm the targeted hot
line/method from the net10 trace actually shrank (e.g. System.Array.Copy self-time dropping). A faster Mean with the targeted frame unchanged is usually noise or an unrelated win.
Quick reference: ratios from real benchmarks
All numbers are from the smoke benchmarks in the repo's perf project. Treat as order-of-magnitude, not exact - rerun before claiming a specific number in a PR.
| Decision | Net481 effect (length 4096, full scan) | | --- | --- | | typeof(T) specialization vs generic IEquatable loop | 1.42× faster | | [AggressiveInlining] on a tight scalar loop (length 16) | 1.82× → 1.07× vs baseline | | Unroll-4 indexed (ptr[0..3] + ptr += 4) | 1.5× faster than scalar | | Unroll-8 same form | 1.6× slower than scalar at 256+ | | Per-iteration *ptr; ptr++ instead of indexed reads | ~1.4× slower than indexed | | Integer-indexed unroll (ptr[i+0..3]; i += 4) | Worse than the scalar baseline | | Branchless *ptr = v == old ? new : v (sparse matches) | 1.5-3× slower than branchful conditional store | | SWAR haszero for char Replace (dense matches) | 3× slower than scalar | | BCL IndexOf for Replace (full-scan) | 2.18-3.08× slower than specialized scalar | | BCL IndexOf for Count (sparse matches, 1/64 density) | 2-3× faster than full-scan specialization | | Exponential SequenceEqual probe for CommonPrefixLength (4096, full match) | 3.3× faster than per-element scalar | | Tuple swap (a, b) = (b, a) for plain locals | ~23% slower than T t = a; a = b; b = t; | | Tuple swap on paired Span indexed swap (sort hot path) | ~9% slower than explicit temps | | Tuple swap on a single Span indexed swap or two ref locals | Equivalent (within noise) |
The two BCL rows look contradictory. They aren't. See [bcl-tradeoffs.md](bcl-tradeoffs.md).
Sub-pages
- [specialization.md](specialization.md) -
typeof(T)pattern,Unsafe.As,
primitive bit-equality classes, when generic methods get inlined.
- [unrolling.md](unrolling.md) - the only unroll form that wins on
net481,
and three that don't.
- [bcl-tradeoffs.md](bcl-tradeoffs.md) - when to defer to BCL
IndexOf/
SequenceEqual on net481 despite no vectorization.
- [antipatterns.md](antipatterns.md) - specific tricks that look clever but
regress on the older JIT.
- [modern-net.md](modern-net.md) - the
net10counterpart: BCL-first
(SearchValues/TensorPrimitives), the canonical vectorized loop, hardware intrinsics, struct-generic kernels, sealing/devirtualization, escape analysis, and why to keep the modern source simple.
- [cross-tfm-codegen.md](cross-tfm-codegen.md) - fundamentals for both targets:
division/modulo lowering, uint-for-non-negative, BitOperations, struct field ordering, AoS->SoA, false sharing, ReadOnlySpan blobs, [InlineArray], const-vs-static readonly, and hot-path allocation anti-patterns.
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.