@cratis/pi 7.102.0 → 7.103.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/package/corpus/harnesses/copilot/instructions/profiles.instructions.md +10 -1
  2. package/package/corpus/harnesses/copilot/instructions/pull-requests.instructions.md +2 -0
  3. package/package/corpus/harnesses/copilot/instructions/secrets.instructions.md +4 -0
  4. package/package/corpus/hooks/README.md +11 -1
  5. package/package/corpus/hooks/scripts/cratis-check-pr.mjs +12 -1
  6. package/package/corpus/hooks/scripts/cratis-guard-secrets.sh +79 -23
  7. package/package/corpus/hooks/scripts/cratis-guard-writes.sh +145 -40
  8. package/package/corpus/rules/profiles.md +10 -1
  9. package/package/corpus/rules/pull-requests.md +2 -0
  10. package/package/corpus/rules/secrets.md +4 -0
  11. package/package/corpus/skills/analyzing-dotnet-performance/LICENSE +23 -0
  12. package/package/corpus/skills/analyzing-dotnet-performance/NOTICE +36 -0
  13. package/package/corpus/skills/analyzing-dotnet-performance/SKILL.md +214 -0
  14. package/package/corpus/skills/analyzing-dotnet-performance/references/async-patterns.md +122 -0
  15. package/package/corpus/skills/analyzing-dotnet-performance/references/collections-and-linq.md +220 -0
  16. package/package/corpus/skills/analyzing-dotnet-performance/references/critical-patterns.md +291 -0
  17. package/package/corpus/skills/analyzing-dotnet-performance/references/io-and-serialization.md +135 -0
  18. package/package/corpus/skills/analyzing-dotnet-performance/references/memory-and-strings.md +219 -0
  19. package/package/corpus/skills/analyzing-dotnet-performance/references/regex-patterns.md +95 -0
  20. package/package/corpus/skills/analyzing-dotnet-performance/references/structural-patterns.md +38 -0
  21. package/package/corpus/skills/binlog-generation/LICENSE +23 -0
  22. package/package/corpus/skills/binlog-generation/NOTICE +22 -0
  23. package/package/corpus/skills/binlog-generation/SKILL.md +129 -0
  24. package/package/corpus/skills/check-bin-obj-clash/LICENSE +23 -0
  25. package/package/corpus/skills/check-bin-obj-clash/NOTICE +27 -0
  26. package/package/corpus/skills/check-bin-obj-clash/SKILL.md +127 -0
  27. package/package/corpus/skills/check-bin-obj-clash/references/common-causes-and-fixes.md +206 -0
  28. package/package/corpus/skills/coverage-analysis/LICENSE +23 -0
  29. package/package/corpus/skills/coverage-analysis/NOTICE +32 -0
  30. package/package/corpus/skills/coverage-analysis/SKILL.md +198 -0
  31. package/package/corpus/skills/coverage-analysis/references/guidelines.md +68 -0
  32. package/package/corpus/skills/coverage-analysis/references/output-format.md +91 -0
  33. package/package/corpus/skills/coverage-analysis/references/report-generation.md +58 -0
  34. package/package/corpus/skills/coverage-analysis/references/setup-discovery.md +307 -0
  35. package/package/corpus/skills/coverage-analysis/scripts/Compute-CrapScores.ps1 +80 -0
  36. package/package/corpus/skills/coverage-analysis/scripts/CoverageData.ps1 +272 -0
  37. package/package/corpus/skills/coverage-analysis/scripts/Extract-MethodCoverage.ps1 +65 -0
  38. package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +26 -1
  39. package/package/corpus/skills/cratis-screenplay-projections/SKILL.md +17 -0
  40. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/SKILL.md +17 -0
  41. package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +8 -0
  42. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +1 -1
  43. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +1 -0
  44. package/package/corpus/skills/cratis-screenplay-toolchain/references/fast-path.md +7 -0
  45. package/package/corpus/skills/cratis-screenplay-toolchain/references/traps.md +1 -0
  46. package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +40 -0
  47. package/package/corpus/skills/cratis-screenplay-ui-composition/references/response-continuations.md +1 -0
  48. package/package/corpus/skills/cratis-screenplay-ui-composition/references/worked-flow.md +1 -0
  49. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +3 -2
  50. package/package/corpus/skills/csharp-refactoring/LICENSE +23 -0
  51. package/package/corpus/skills/csharp-refactoring/NOTICE +22 -0
  52. package/package/corpus/skills/csharp-refactoring/SKILL.md +175 -0
  53. package/package/corpus/skills/csharp-refactoring/references/operation-catalog.md +37 -0
  54. package/package/corpus/skills/directory-build-organization/LICENSE +23 -0
  55. package/package/corpus/skills/directory-build-organization/NOTICE +21 -0
  56. package/package/corpus/skills/directory-build-organization/SKILL.md +205 -0
  57. package/package/corpus/skills/directory-build-organization/references/common-patterns.md +56 -0
  58. package/package/corpus/skills/directory-build-organization/references/multi-level-examples.md +167 -0
  59. package/package/corpus/skills/directory-build-organization/references/targetframework-props-pitfall.md +54 -0
  60. package/package/corpus/skills/dotnet-aot-compat/LICENSE +23 -0
  61. package/package/corpus/skills/dotnet-aot-compat/NOTICE +18 -0
  62. package/package/corpus/skills/dotnet-aot-compat/SKILL.md +265 -0
  63. package/package/corpus/skills/dotnet-aot-compat/references/polyfills.md +43 -0
  64. package/package/corpus/skills/dotnet-trace-collect/LICENSE +23 -0
  65. package/package/corpus/skills/dotnet-trace-collect/NOTICE +65 -0
  66. package/package/corpus/skills/dotnet-trace-collect/SKILL.md +116 -0
  67. package/package/corpus/skills/dotnet-trace-collect/references/dotnet-monitor.md +97 -0
  68. package/package/corpus/skills/dotnet-trace-collect/references/dotnet-trace-collect-linux.md +84 -0
  69. package/package/corpus/skills/dotnet-trace-collect/references/dotnet-trace-collect.md +91 -0
  70. package/package/corpus/skills/dotnet-trace-collect/references/perfcollect.md +200 -0
  71. package/package/corpus/skills/dotnet-trace-collect/references/perfview.md +141 -0
  72. package/package/corpus/skills/dotnet-trace-collect/references/tool-selection.md +160 -0
  73. package/package/corpus/skills/dump-collect/LICENSE +23 -0
  74. package/package/corpus/skills/dump-collect/NOTICE +40 -0
  75. package/package/corpus/skills/dump-collect/SKILL.md +97 -0
  76. package/package/corpus/skills/dump-collect/references/container-dumps.md +412 -0
  77. package/package/corpus/skills/dump-collect/references/coreclr-dumps.md +108 -0
  78. package/package/corpus/skills/dump-collect/references/nativeaot-dumps.md +280 -0
  79. package/package/corpus/skills/eliminate-redundant-restores/LICENSE +23 -0
  80. package/package/corpus/skills/eliminate-redundant-restores/NOTICE +19 -0
  81. package/package/corpus/skills/eliminate-redundant-restores/SKILL.md +112 -0
  82. package/package/corpus/skills/extension-points/LICENSE +23 -0
  83. package/package/corpus/skills/extension-points/NOTICE +18 -0
  84. package/package/corpus/skills/extension-points/SKILL.md +248 -0
  85. package/package/corpus/skills/filter-syntax/LICENSE +23 -0
  86. package/package/corpus/skills/filter-syntax/NOTICE +17 -0
  87. package/package/corpus/skills/filter-syntax/SKILL.md +179 -0
  88. package/package/corpus/skills/including-generated-files/LICENSE +23 -0
  89. package/package/corpus/skills/including-generated-files/NOTICE +17 -0
  90. package/package/corpus/skills/including-generated-files/SKILL.md +139 -0
  91. package/package/corpus/skills/microbenchmarking/LICENSE +23 -0
  92. package/package/corpus/skills/microbenchmarking/NOTICE +36 -0
  93. package/package/corpus/skills/microbenchmarking/SKILL.md +131 -0
  94. package/package/corpus/skills/microbenchmarking/references/bdn-internals-and-tuning.md +143 -0
  95. package/package/corpus/skills/microbenchmarking/references/comparison-strategies.md +200 -0
  96. package/package/corpus/skills/microbenchmarking/references/diagnosers-and-exporters.md +150 -0
  97. package/package/corpus/skills/microbenchmarking/references/project-setup-and-running.md +189 -0
  98. package/package/corpus/skills/microbenchmarking/references/writing-benchmarks.md +310 -0
  99. package/package/corpus/skills/msbuild/LICENSE +23 -0
  100. package/package/corpus/skills/msbuild/NOTICE +55 -0
  101. package/package/corpus/skills/msbuild/SKILL.md +117 -0
  102. package/package/corpus/skills/msbuild/references/antipatterns/additional-antipatterns.md +291 -0
  103. package/package/corpus/skills/msbuild/references/antipatterns/incremental-build-inputs-outputs.md +57 -0
  104. package/package/corpus/skills/msbuild/references/antipatterns/private-assets.md +29 -0
  105. package/package/corpus/skills/msbuild/references/binlog-failure-analysis.md +85 -0
  106. package/package/corpus/skills/msbuild/references/binlog-generation.md +69 -0
  107. package/package/corpus/skills/msbuild/references/build-perf-baseline.md +493 -0
  108. package/package/corpus/skills/msbuild/references/build-perf-diagnostics.md +268 -0
  109. package/package/corpus/skills/msbuild/references/copy-to-output-directory.md +183 -0
  110. package/package/corpus/skills/msbuild/references/eval-performance.md +190 -0
  111. package/package/corpus/skills/msbuild/references/extension-points.md +281 -0
  112. package/package/corpus/skills/msbuild/references/incremental-build.md +365 -0
  113. package/package/corpus/skills/msbuild/references/msbuild-antipatterns.md +401 -0
  114. package/package/corpus/skills/orleans/LICENSE +21 -0
  115. package/package/corpus/skills/orleans/NOTICE +64 -0
  116. package/package/corpus/skills/orleans/SKILL.md +140 -0
  117. package/package/corpus/skills/orleans/references/anti-patterns.md +660 -0
  118. package/package/corpus/skills/orleans/references/configuration-api.md +933 -0
  119. package/package/corpus/skills/orleans/references/examples.md +66 -0
  120. package/package/corpus/skills/orleans/references/grain-api.md +784 -0
  121. package/package/corpus/skills/orleans/references/grains.md +75 -0
  122. package/package/corpus/skills/orleans/references/hosting.md +71 -0
  123. package/package/corpus/skills/orleans/references/implementation.md +591 -0
  124. package/package/corpus/skills/orleans/references/official-docs-index.md +250 -0
  125. package/package/corpus/skills/orleans/references/patterns.md +811 -0
  126. package/package/corpus/skills/orleans/references/persistence-api.md +495 -0
  127. package/package/corpus/skills/orleans/references/primitive-selection.md +35 -0
  128. package/package/corpus/skills/orleans/references/scheduling-and-services.md +295 -0
  129. package/package/corpus/skills/orleans/references/serialization-api.md +299 -0
  130. package/package/corpus/skills/orleans/references/streaming-api.md +396 -0
  131. package/package/corpus/skills/orleans/references/testing-patterns.md +210 -0
  132. package/package/corpus/skills/platform-detection/LICENSE +23 -0
  133. package/package/corpus/skills/platform-detection/NOTICE +17 -0
  134. package/package/corpus/skills/platform-detection/SKILL.md +230 -0
  135. package/package/corpus/skills/platform-detection/references/command-mode.md +27 -0
  136. package/package/corpus/skills/profiling/LICENSE +21 -0
  137. package/package/corpus/skills/profiling/NOTICE +50 -0
  138. package/package/corpus/skills/profiling/SKILL.md +144 -0
  139. package/package/corpus/skills/profiling/references/commands.md +439 -0
  140. package/package/corpus/skills/profiling/references/patterns.md +586 -0
  141. package/package/corpus/skills/profiling/references/profiling.md +190 -0
  142. package/package/corpus/skills/run-tests/LICENSE +23 -0
  143. package/package/corpus/skills/run-tests/NOTICE +19 -0
  144. package/package/corpus/skills/run-tests/SKILL.md +305 -0
  145. package/package/corpus/skills/target-authoring/LICENSE +23 -0
  146. package/package/corpus/skills/target-authoring/NOTICE +17 -0
  147. package/package/corpus/skills/target-authoring/SKILL.md +165 -0
  148. package/package/corpus/skills/vectorization/LICENSE +23 -0
  149. package/package/corpus/skills/vectorization/NOTICE +17 -0
  150. package/package/corpus/skills/vectorization/SKILL.md +189 -0
  151. package/package/profile-catalog.json +85 -1
  152. package/package.json +1 -1
@@ -0,0 +1,586 @@
1
+ # .NET Profiling Patterns Reference
2
+
3
+ ## Contents
4
+
5
+ - CPU Profiling Patterns
6
+ - Memory Profiling Patterns
7
+ - GC Analysis Patterns
8
+ - Contention Profiling Patterns
9
+ - Exception Profiling Patterns
10
+ - Startup Profiling Patterns
11
+ - Production Profiling Patterns
12
+ - Comparison and Benchmarking Patterns
13
+ - Tool Selection Guide
14
+
15
+ This reference covers common profiling patterns for CPU, memory, GC, and performance analysis in .NET applications.
16
+
17
+ ---
18
+
19
+ ## CPU Profiling Patterns
20
+
21
+ ### Pattern: CPU Hotspot Analysis
22
+
23
+ **When to use**: Application is slow or using excessive CPU.
24
+
25
+ **Approach**:
26
+ 1. Ensure the application is running under realistic load
27
+ 2. Collect a CPU sampling trace
28
+ 3. Analyze the flame graph for time-consuming methods
29
+ 4. Focus on your code, not framework internals
30
+
31
+ ```bash
32
+ # Collect CPU sampling trace
33
+ dotnet-trace collect --process-id <PID> --profile cpu-sampling --duration 00:00:30
34
+
35
+ # Convert for visualization
36
+ dotnet-trace convert trace.nettrace --format Speedscope
37
+ ```
38
+
39
+ **Analysis checklist**:
40
+ - [ ] Identify top 5 methods by inclusive time
41
+ - [ ] Look for unexpected methods in hot paths
42
+ - [ ] Check for string operations in loops
43
+ - [ ] Check for repeated allocations causing GC
44
+ - [ ] Check for synchronous I/O blocking threads
45
+
46
+ ### Pattern: Method-Level Timing
47
+
48
+ **When to use**: Need precise timing for specific operations.
49
+
50
+ **Approach**:
51
+ 1. Add `System.Diagnostics.Activity` or `Stopwatch` instrumentation
52
+ 2. Use EventCounters for custom metrics
53
+ 3. Collect with dotnet-counters
54
+
55
+ ```csharp
56
+ // Custom EventCounter for method timing
57
+ public class OperationMetrics : EventSource
58
+ {
59
+ public static readonly OperationMetrics Instance = new();
60
+
61
+ private readonly IncrementingEventCounter _operationCount;
62
+ private readonly EventCounter _operationDuration;
63
+
64
+ public OperationMetrics()
65
+ {
66
+ _operationCount = new IncrementingEventCounter("operation-count", this);
67
+ _operationDuration = new EventCounter("operation-duration-ms", this);
68
+ }
69
+
70
+ public void RecordOperation(double durationMs)
71
+ {
72
+ _operationCount.Increment();
73
+ _operationDuration.WriteMetric(durationMs);
74
+ }
75
+ }
76
+ ```
77
+
78
+ ```bash
79
+ # Monitor custom counters
80
+ dotnet-counters monitor --process-id <PID> \
81
+ --counters "MyApp.OperationMetrics[operation-count,operation-duration-ms]"
82
+ ```
83
+
84
+ ### Pattern: Thread Pool Starvation Detection
85
+
86
+ **When to use**: Application becomes unresponsive under load.
87
+
88
+ **Symptoms**:
89
+ - High thread pool queue length
90
+ - Increasing response times
91
+ - Thread count growing continuously
92
+
93
+ ```bash
94
+ # Monitor thread pool health
95
+ dotnet-counters monitor --process-id <PID> \
96
+ --counters "System.Runtime[threadpool-thread-count,threadpool-queue-length,threadpool-completed-items-count]"
97
+ ```
98
+
99
+ **Thresholds to watch**:
100
+ - `threadpool-queue-length` > 0 sustained indicates starvation
101
+ - `threadpool-thread-count` growing continuously indicates blocking calls
102
+ - High `threadpool-completed-items-count` with high queue length indicates throughput issues
103
+
104
+ **Common causes**:
105
+ - Sync-over-async (calling `.Result` or `.Wait()`)
106
+ - Blocking I/O on thread pool threads
107
+ - Long-running synchronous work on thread pool
108
+ - Too many concurrent operations
109
+
110
+ ---
111
+
112
+ ## Memory Profiling Patterns
113
+
114
+ ### Pattern: Memory Leak Detection
115
+
116
+ **When to use**: Memory grows continuously over time.
117
+
118
+ **Approach**:
119
+ 1. Establish baseline memory usage
120
+ 2. Run under load for extended period
121
+ 3. Take periodic GC dumps
122
+ 4. Compare heap snapshots
123
+
124
+ ```bash
125
+ # Baseline snapshot
126
+ dotnet-gcdump collect --process-id <PID> --output baseline.gcdump
127
+
128
+ # After load test
129
+ dotnet-gcdump collect --process-id <PID> --output afterload.gcdump
130
+
131
+ # Generate reports
132
+ dotnet-gcdump report baseline.gcdump > baseline-report.txt
133
+ dotnet-gcdump report afterload.gcdump > afterload-report.txt
134
+ ```
135
+
136
+ **Analysis steps**:
137
+ 1. Compare type counts between snapshots
138
+ 2. Look for types with growing instance counts
139
+ 3. Identify retained object graphs
140
+ 4. Check for event handler subscriptions
141
+ 5. Check for static collections
142
+
143
+ ### Pattern: Large Object Heap (LOH) Analysis
144
+
145
+ **When to use**: GC pauses are long or memory fragmentation suspected.
146
+
147
+ **Symptoms**:
148
+ - Gen 2 GC frequency increasing
149
+ - Long GC pause times
150
+ - High memory usage despite low live object count
151
+
152
+ ```bash
153
+ # Collect GC verbose trace
154
+ dotnet-trace collect --process-id <PID> --profile gc-verbose --duration 00:01:00
155
+ ```
156
+
157
+ **Common LOH issues**:
158
+ - Arrays > 85,000 bytes allocated frequently
159
+ - String concatenation creating large strings
160
+ - Large buffers not pooled
161
+ - Byte arrays from serialization
162
+
163
+ **Mitigations**:
164
+ ```csharp
165
+ // Use ArrayPool for large buffers
166
+ var buffer = ArrayPool<byte>.Shared.Rent(100000);
167
+ try
168
+ {
169
+ // Use buffer
170
+ }
171
+ finally
172
+ {
173
+ ArrayPool<byte>.Shared.Return(buffer);
174
+ }
175
+
176
+ // Use string pooling
177
+ var pooledString = string.Intern(frequentlyUsedString);
178
+
179
+ // Use Span<T> to avoid allocations
180
+ ReadOnlySpan<byte> span = stackalloc byte[256];
181
+ ```
182
+
183
+ ### Pattern: Allocation Rate Analysis
184
+
185
+ **When to use**: GC running too frequently.
186
+
187
+ ```bash
188
+ # Monitor allocation rate
189
+ dotnet-counters monitor --process-id <PID> \
190
+ --counters "System.Runtime[alloc-rate,gc-heap-size,gen-0-gc-count,gen-1-gc-count,gen-2-gc-count]"
191
+ ```
192
+
193
+ **Thresholds to watch**:
194
+ - `alloc-rate` > 100 MB/s may cause GC pressure
195
+ - Frequent Gen 0 collections (> 10/sec) indicate high allocation
196
+ - Gen 2 collections > 1/min may indicate LOH issues or leaks
197
+
198
+ **Allocation hotspot trace**:
199
+ ```bash
200
+ # Collect allocation events
201
+ dotnet-trace collect --process-id <PID> \
202
+ --providers "Microsoft-Windows-DotNETRuntime:0x80000:4"
203
+ ```
204
+
205
+ ---
206
+
207
+ ## GC Analysis Patterns
208
+
209
+ ### Pattern: GC Pause Analysis
210
+
211
+ **When to use**: Application has latency spikes correlated with GC.
212
+
213
+ ```bash
214
+ # Collect detailed GC events
215
+ dotnet-trace collect --process-id <PID> \
216
+ --profile gc-verbose \
217
+ --duration 00:02:00
218
+ ```
219
+
220
+ **Key metrics to extract**:
221
+ - GC pause duration per generation
222
+ - GC frequency per generation
223
+ - Promoted bytes per collection
224
+ - Fragmentation percentage
225
+
226
+ ### Pattern: GC Mode Selection
227
+
228
+ **Server GC vs Workstation GC**:
229
+
230
+ | Characteristic | Server GC | Workstation GC |
231
+ |---------------|-----------|----------------|
232
+ | Threads | One per CPU core | Single thread |
233
+ | Heap | Segmented per core | Single heap |
234
+ | Latency | Higher pause times | Lower pause times |
235
+ | Throughput | Higher throughput | Lower throughput |
236
+ | Memory | Higher memory usage | Lower memory usage |
237
+ | Best for | Server workloads | Desktop apps |
238
+
239
+ ```xml
240
+ <!-- Enable server GC in .csproj -->
241
+ <PropertyGroup>
242
+ <ServerGarbageCollection>true</ServerGarbageCollection>
243
+ </PropertyGroup>
244
+ ```
245
+
246
+ ```json
247
+ // Or in runtimeconfig.json
248
+ {
249
+ "runtimeOptions": {
250
+ "configProperties": {
251
+ "System.GC.Server": true
252
+ }
253
+ }
254
+ }
255
+ ```
256
+
257
+ ### Pattern: Concurrent vs Background GC Analysis
258
+
259
+ ```bash
260
+ # Monitor GC behavior
261
+ dotnet-counters monitor --process-id <PID> \
262
+ --counters "System.Runtime[gc-heap-size,gen-0-gc-count,gen-1-gc-count,gen-2-gc-count,time-in-gc]"
263
+ ```
264
+
265
+ **time-in-gc interpretation**:
266
+ - < 5%: Healthy
267
+ - 5-10%: Monitor closely
268
+ - > 10%: GC tuning needed
269
+
270
+ ### Pattern: Pinned Object Analysis
271
+
272
+ **When to use**: Suspected fragmentation from pinned objects.
273
+
274
+ ```bash
275
+ # Analyze pinned objects in dump
276
+ dotnet-dump analyze mydump.dmp
277
+ > gcheapstat
278
+ > dumpheap -stat
279
+ ```
280
+
281
+ **Common pinning issues**:
282
+ - Interop callbacks holding managed references
283
+ - Async I/O buffers
284
+ - Native code integration
285
+
286
+ ---
287
+
288
+ ## Contention Profiling Patterns
289
+
290
+ ### Pattern: Lock Contention Analysis
291
+
292
+ **When to use**: Application throughput limited by synchronization.
293
+
294
+ ```bash
295
+ # Collect contention events
296
+ dotnet-trace collect --process-id <PID> \
297
+ --providers "Microsoft-Windows-DotNETRuntime:0x4000:4"
298
+ ```
299
+
300
+ **Analysis steps**:
301
+ 1. Identify frequently contended locks
302
+ 2. Analyze lock hold times
303
+ 3. Look for lock ordering issues
304
+ 4. Check for unnecessary locking
305
+
306
+ ### Pattern: Thread Synchronization Overhead
307
+
308
+ ```bash
309
+ # Monitor thread-related counters
310
+ dotnet-counters monitor --process-id <PID> \
311
+ --counters "System.Runtime[monitor-lock-contention-count,threadpool-thread-count]"
312
+ ```
313
+
314
+ **High contention indicators**:
315
+ - `monitor-lock-contention-count` growing rapidly
316
+ - Thread count higher than expected
317
+ - CPU usage lower than expected under load
318
+
319
+ **Mitigations**:
320
+ ```csharp
321
+ // Use lock-free collections
322
+ var dict = new ConcurrentDictionary<string, int>();
323
+
324
+ // Use reader-writer locks for read-heavy workloads
325
+ var rwLock = new ReaderWriterLockSlim();
326
+
327
+ // Use Interlocked for simple operations
328
+ Interlocked.Increment(ref counter);
329
+
330
+ // Use async semaphores
331
+ var semaphore = new SemaphoreSlim(maxConcurrency);
332
+ await semaphore.WaitAsync();
333
+ ```
334
+
335
+ ---
336
+
337
+ ## Exception Profiling Patterns
338
+
339
+ ### Pattern: Exception Rate Analysis
340
+
341
+ **When to use**: Performance impacted by exception handling.
342
+
343
+ ```bash
344
+ # Monitor exception count
345
+ dotnet-counters monitor --process-id <PID> \
346
+ --counters "System.Runtime[exception-count]"
347
+
348
+ # Collect exception events with stack traces
349
+ dotnet-trace collect --process-id <PID> \
350
+ --providers "Microsoft-Windows-DotNETRuntime:0x8000:4"
351
+ ```
352
+
353
+ **Thresholds**:
354
+ - < 10 exceptions/sec: Normal
355
+ - 10-100 exceptions/sec: Review exception usage
356
+ - > 100 exceptions/sec: Performance impact likely
357
+
358
+ **Common exception anti-patterns**:
359
+ ```csharp
360
+ // Anti-pattern: Using exceptions for flow control
361
+ try
362
+ {
363
+ value = dict[key];
364
+ }
365
+ catch (KeyNotFoundException)
366
+ {
367
+ value = default;
368
+ }
369
+
370
+ // Better: Use TryGetValue
371
+ if (!dict.TryGetValue(key, out value))
372
+ {
373
+ value = default;
374
+ }
375
+ ```
376
+
377
+ ### Pattern: First-Chance Exception Analysis
378
+
379
+ ```bash
380
+ # Collect first-chance exceptions
381
+ dotnet-trace collect --process-id <PID> \
382
+ --providers "Microsoft-Windows-DotNETRuntime:0x8000:5"
383
+ ```
384
+
385
+ Analyze the trace to find:
386
+ - Exception types thrown frequently
387
+ - Exception origins (your code vs framework)
388
+ - Exception handling patterns
389
+
390
+ ---
391
+
392
+ ## Startup Profiling Patterns
393
+
394
+ ### Pattern: Cold Start Analysis
395
+
396
+ **When to use**: Application startup is slow.
397
+
398
+ ```bash
399
+ # Trace from application launch
400
+ dotnet-trace collect \
401
+ --output startup-trace.nettrace \
402
+ -- dotnet run --project MyApp.csproj
403
+
404
+ # Or with specific configuration
405
+ dotnet-trace collect \
406
+ --output startup-trace.nettrace \
407
+ -- dotnet run -c Release --project MyApp.csproj
408
+ ```
409
+
410
+ **Startup phases to analyze**:
411
+ 1. CLR initialization
412
+ 2. Assembly loading
413
+ 3. JIT compilation
414
+ 4. Type initialization (static constructors)
415
+ 5. Dependency injection setup
416
+ 6. Application initialization
417
+
418
+ ### Pattern: Assembly Loading Analysis
419
+
420
+ ```bash
421
+ # Collect loader events
422
+ dotnet-trace collect --process-id <PID> \
423
+ --providers "Microsoft-Windows-DotNETRuntime:0x8:4"
424
+ ```
425
+
426
+ **Optimization strategies**:
427
+ - Use ReadyToRun (R2R) compilation
428
+ - Lazy-load optional assemblies
429
+ - Use trimming for single-file apps
430
+ - Profile and defer non-critical initialization
431
+
432
+ ```xml
433
+ <!-- Enable ReadyToRun -->
434
+ <PropertyGroup>
435
+ <PublishReadyToRun>true</PublishReadyToRun>
436
+ </PropertyGroup>
437
+ ```
438
+
439
+ ### Pattern: JIT Compilation Analysis
440
+
441
+ ```bash
442
+ # Collect JIT events
443
+ dotnet-trace collect --process-id <PID> \
444
+ --providers "Microsoft-Windows-DotNETRuntime:0x10:4"
445
+ ```
446
+
447
+ **JIT optimization strategies**:
448
+ - Use tiered compilation (default in .NET Core 3.0+)
449
+ - Pre-JIT critical paths with warmup
450
+ - Use AOT/R2R for startup-sensitive scenarios
451
+
452
+ ---
453
+
454
+ ## Production Profiling Patterns
455
+
456
+ ### Pattern: Low-Overhead Production Monitoring
457
+
458
+ **Approach**: Use dotnet-counters for continuous, low-impact monitoring.
459
+
460
+ ```bash
461
+ # Lightweight monitoring script
462
+ #!/bin/bash
463
+ while true; do
464
+ dotnet-counters collect \
465
+ --process-id $APP_PID \
466
+ --counters "System.Runtime[cpu-usage,working-set,gc-heap-size,exception-count]" \
467
+ --output metrics-$(date +%Y%m%d-%H%M%S).csv \
468
+ --format csv \
469
+ --duration 60
470
+ done
471
+ ```
472
+
473
+ ### Pattern: Triggered Diagnostics Collection
474
+
475
+ **Approach**: Collect detailed diagnostics only when anomalies detected.
476
+
477
+ ```bash
478
+ # Collect trace when CPU exceeds threshold
479
+ CPU_THRESHOLD=80
480
+
481
+ while true; do
482
+ CPU=$(dotnet-counters monitor --process-id $APP_PID \
483
+ --counters "System.Runtime[cpu-usage]" \
484
+ --duration 5 2>/dev/null | grep cpu-usage | awk '{print $2}')
485
+
486
+ if (( $(echo "$CPU > $CPU_THRESHOLD" | bc -l) )); then
487
+ dotnet-trace collect --process-id $APP_PID \
488
+ --profile cpu-sampling \
489
+ --duration 00:00:30 \
490
+ --output high-cpu-$(date +%Y%m%d-%H%M%S).nettrace
491
+ fi
492
+
493
+ sleep 60
494
+ done
495
+ ```
496
+
497
+ ### Pattern: Memory Dump on OOM
498
+
499
+ ```bash
500
+ # Configure automatic dump on OOM
501
+ export DOTNET_DbgEnableMiniDump=1
502
+ export DOTNET_DbgMiniDumpType=4
503
+ export DOTNET_DbgMiniDumpName=/var/dumps/oom-%p-%t.dmp
504
+
505
+ # Run application
506
+ dotnet MyApp.dll
507
+ ```
508
+
509
+ ---
510
+
511
+ ## Comparison and Benchmarking Patterns
512
+
513
+ ### Pattern: Before/After Comparison
514
+
515
+ **Approach**: Collect identical metrics before and after changes.
516
+
517
+ ```bash
518
+ # Baseline collection
519
+ dotnet-counters collect --process-id $BASELINE_PID \
520
+ --counters System.Runtime \
521
+ --output baseline-counters.csv \
522
+ --format csv \
523
+ --duration 300
524
+
525
+ # After optimization
526
+ dotnet-counters collect --process-id $OPTIMIZED_PID \
527
+ --counters System.Runtime \
528
+ --output optimized-counters.csv \
529
+ --format csv \
530
+ --duration 300
531
+ ```
532
+
533
+ **Comparison checklist**:
534
+ - [ ] Same workload profile
535
+ - [ ] Same duration
536
+ - [ ] Same warmup period
537
+ - [ ] Same hardware/environment
538
+ - [ ] Multiple runs for statistical significance
539
+
540
+ ### Pattern: Regression Detection
541
+
542
+ **Approach**: Establish performance baselines in CI.
543
+
544
+ ```bash
545
+ # CI performance check script
546
+ #!/bin/bash
547
+ set -e
548
+
549
+ # Run app with load
550
+ ./start-load-test.sh &
551
+ LOAD_PID=$!
552
+
553
+ # Collect metrics
554
+ dotnet-counters collect --process-id $APP_PID \
555
+ --counters System.Runtime \
556
+ --output ci-metrics.csv \
557
+ --format csv \
558
+ --duration 60
559
+
560
+ # Stop load test
561
+ kill $LOAD_PID
562
+
563
+ # Compare against baseline (example threshold check)
564
+ ALLOC_RATE=$(grep alloc-rate ci-metrics.csv | awk -F',' '{sum+=$2; count++} END {print sum/count}')
565
+ BASELINE_ALLOC_RATE=50000000 # 50 MB/s
566
+
567
+ if (( $(echo "$ALLOC_RATE > $BASELINE_ALLOC_RATE * 1.2" | bc -l) )); then
568
+ echo "REGRESSION: Allocation rate increased by >20%"
569
+ exit 1
570
+ fi
571
+ ```
572
+
573
+ ---
574
+
575
+ ## Tool Selection Guide
576
+
577
+ | Symptom | Primary Tool | Secondary Tool |
578
+ |---------|-------------|----------------|
579
+ | High CPU | dotnet-trace (cpu-sampling) | dotnet-counters |
580
+ | Memory growth | dotnet-gcdump | dotnet-dump |
581
+ | GC pauses | dotnet-trace (gc-verbose) | dotnet-counters |
582
+ | Slow startup | dotnet-trace (from launch) | - |
583
+ | Lock contention | dotnet-trace (contention) | dotnet-counters |
584
+ | Exception storms | dotnet-counters | dotnet-trace |
585
+ | Crash analysis | dotnet-dump | - |
586
+ | Live health | dotnet-counters | - |