用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/rudironsoni/Synaxis --skill dotnet-performance-patterns命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
AI-powered wiki generation for code repositories with commands, agents, and skills
Routes .NET/C# work to domain skills. Loads coding-standards for code paths.
Skill manifest management for dotnet-agent-harness. Tracks skill dependencies, conflicts, version compatibility, and provides validation and resolution tools. Triggers on: skill manifest, dependency resolution, skill compatibility, version conflicts, build manifest, validate dependencies.
基于 SOC 职业分类
正在显示 SKILL.md
| name | dotnet-performance-patterns |
| description | Optimizes .NET allocations and throughput. Span, ArrayPool, ref struct, sealed, stackalloc. |
| license | MIT |
| targets | ["*"] |
| category | performance |
| subcategory | patterns |
| tags | ["performance","dotnet","skill","patterns","span","memory"] |
| version | 1.0.0 |
| author | dotnet-agent-harness |
| invocable | true |
| related_skills | ["dotnet-gc-memory","dotnet-benchmarkdotnet","dotnet-csharp-type-design-performance","dotnet-native-aot"] |
| claudecode | {"allowed-tools":["Read","Grep","Glob","Bash","Write","Edit"]} |
| codexcli | {"short-description":".NET skill guidance for foundation tasks"} |
| opencode | {"allowed-tools":["Read","Grep","Glob","Bash","Write","Edit"]} |
| copilot | {} |
| geminicli | {} |
| antigravity | {} |
Performance-oriented architecture patterns for .NET applications. Covers zero-allocation coding with Span<T> and Memory<T>, buffer pooling with ArrayPool<T>, struct design for performance (readonly struct, ref struct, in parameters), sealed class devirtualization by the JIT, stack-based allocation with stackalloc, and string handling performance. Focuses on the why (performance rationale and measurement) rather than the how (language syntax).
Version assumptions: .NET 8.0+ baseline. Span<T> and Memory<T> are available from .NET Core 2.1+ but this skill targets modern usage patterns on .NET 8+.
Cross-references: [skill:dotnet-benchmarkdotnet] for measuring the impact of these patterns, [skill:dotnet-csharp-modern-patterns] for Span/Memory syntax foundation, [skill:dotnet-csharp-coding-standards] for sealed class style conventions, [skill:dotnet-native-aot] for AOT performance characteristics and trimming impact on pattern choices, [skill:dotnet-serialization] for serialization performance context.
Span<T> provides a safe, bounds-checked view over contiguous memory without allocating. It enables slicing arrays,
strings, and stack memory without copying. For syntax details see [skill:dotnet-csharp-modern-patterns]; this section
focuses on performance rationale.
// BAD: Substring allocates a new string on each call
public static ( Key, Value) ()
{
colonIndex = header.IndexOf();
(header.Substring(, colonIndex), header.Substring(colonIndex + ).Trim());
}
{
colonIndex = header.IndexOf();
(header[..colonIndex], header[(colonIndex + )..].Trim());
}
```text
Performance impact: high-
{
bytesRead = stream.ReadAsync(buffer);
data = buffer[..bytesRead];
ProcessData(data.Span);
}
{
sum = ;
( b data)
sum += b;
sum;
}
```text
---
;
{
buffer = ArrayPool<>.Shared.Rent(minimumLength: );
{
bytesRead = source.Read(buffer, , buffer.Length);
ProcessChunk(buffer.AsSpan(, bytesRead));
}
{
ArrayPool<>.Shared.Return(buffer, clearArray: );
}
}
```text
| Mistake | Impact | Fix |
|---------|--------|-----|
| Using `buffer.Length` instead of requested size | Processes uninitialized bytes beyond actual data | Track requested/actual size separately |
| Forgetting to the buffer | Pool exhaustion, falls back to allocation | Use / a `` wrapper |
| Returning a buffer twice | Corrupts pool state | Null the reference after |
| Not clearing sensitive data | Security leak pooled buffers | Pass `clearArray: ` to `Return` |
---
The JIT must defensively copy non- structs accessed via ``, `` fields, `` methods to prevent mutation. Marking a `` guarantees immutability, eliminating these copies:
```csharp
Point3D
{
X { ; }
Y { ; }
Z { ; }
=> (X, Y, Z) = (x, y, z);
{
dx = X - other.X;
dy = Y - other.Y;
dz = Z - other.Z;
Math.Sqrt(dx * dx + dy * dy + dz * dz);
}
}
```text
Without ``, calling a method a through an `` parameter forces the JIT to copy the entire to protect against mutation. For large structs tight loops, eliminates significant overhead.
` ` types are constrained to the stack. They cannot be boxed, stored fields, used methods. This enables safe wrapping of Span\<T\>:
```csharp
SpanLineEnumerator
{
ReadOnlySpan<> _remaining;
=> _remaining = text;
ReadOnlySpan<> Current { ; ; }
{
(_remaining.IsEmpty)
;
newlineIndex = _remaining.IndexOf();
(newlineIndex == )
{
Current = _remaining;
_remaining = ;
}
{
Current = _remaining[..newlineIndex];
_remaining = _remaining[(newlineIndex + )..];
}
;
}
}
```text
Use `` large structs passed to methods. The ``
=> a.DistanceTo( b);
```csharp
**When to use ``:**
| Struct Size | Recommendation |
|-------------|---------------|
| <= bytes |
{
=> x * ;
}
:
{
=> x * ;
}
{ ; }
```text
Verify devirtualization `[DisassemblyDiagnoser]` [skill:dotnet-benchmarkdotnet]. See [skill:dotnet-csharp-coding-standards] the project convention of defaulting to classes.
Devirtualization + inlining eliminates:
**vtable lookup** -- indirect memory access to find the method pointer
**Call overhead** -- the actual indirect call instruction
**Inlining barrier** -- calls cannot be inlined; methods can
In tight loops hot paths, the cumulative effect measurable. For framework/library types that are designed extension, always prefer ``.
---
`` allocates memory the stack, avoiding GC entirely. Use small, -size buffers hot paths:
```
{
Span<> buffer = [];
guid.TryFormat(buffer, charsWritten, );
(buffer[..charsWritten]);
}
```text
| Guideline | Rationale |
|-----------|-----------|
| ; overflow crashes the process |
| Use constant bounded sizes only | Runtime-variable sizes risk stack overflow malicious/unexpected input |
| Prefer `Span<T>` assignment over raw pointer | Span provides bounds checking; raw pointers |
| Fall back to ArrayPool large/variable sizes | Gracefully handle cases that exceed stack budget |
```
{
stackThreshold = ;
[]? rented = ;
Span<> buffer = input.Length <= stackThreshold
? [stackThreshold]
: (rented = ArrayPool<>.Shared.Rent(input.Length));
{
written = Encoding.UTF8.GetChars(input, buffer);
(buffer[..written]);
}
{
(rented )
ArrayPool<>.Shared.Return(rented);
}
}
```text
This pattern used throughout the .NET runtime libraries the recommended approach methods that handle both small large inputs.
---
Ordinal comparisons are significantly faster than culture-aware comparisons because they avoid Unicode normalization:
```csharp
isMatch = str.Equals(, StringComparison.Ordinal);
containsKey = dict.ContainsKey(key);
isMatchIgnoreCase = str.Equals(, StringComparison.OrdinalIgnoreCase);
isMatchCulture = str.Equals(, StringComparison.CurrentCulture);
```text
**Default guidance:** Use `StringComparison.Ordinal` `StringComparison.OrdinalIgnoreCase` identifiers, dictionary keys, paths, protocol strings. Reserve culture-aware comparison user-visible text sorting display.
The CLR interns compile-time literals automatically. `.Intern()` can reduce memory runtime strings that repeat frequently:
```csharp
normalized = .Intern(headerName.ToLowerInvariant());
```csharp
**Caution:** Interned strings are never garbage collected. Only intern strings a bounded, {a}{b}
Primary approach: Use Serena symbol operations for efficient code navigation:
serena_find_symbol instead of text searchserena_get_symbols_overview for file organizationserena_find_referencing_symbols for impact analysisserena_replace_symbol_body for clean modificationsWhen to use Serena vs traditional tools:
Example workflow:
# Instead of:
Read: src/Services/OrderService.cs
Grep: "public void ProcessOrder"
# Use:
serena_find_symbol: "OrderService/ProcessOrder"
serena_get_symbols_overview: "src/Services/OrderService.cs"