Part 8 · 1 chapters · ~8 min

Performance

Allocation-aware code (structs, Span<T>, stackalloc, pooling), System.IO.Pipelines, source generators for JSON, regex and logging, BenchmarkDotNet with memory diagnostics, thread-pool tuning and starvation, server versus workstation GC and DATAS, EF Core performance, Native AOT trade-offs, and production diagnostics with dotnet-counters, dotnet-trace and dotnet-gcdump.

9

Measure allocations, not just time

code
[MemoryDiagnoser]
public class FeeBench
{
    [Benchmark(Baseline = true)] public long WithClass() { long s = 0; for (int i = 0; i < 1_000; i++) s += new MoneyC(i).Kobo; return s; }
    [Benchmark] public long WithStruct() { long s = 0; for (int i = 0; i < 1_000; i++) s += new MoneyS(i).Kobo; return s; }
}
// dotnet run -c Release → BenchmarkDotNet table: Mean, Error, StdDev, Allocated (B/op)

[GeneratedRegex(@"^\d{10}$")] private static partial Regex Nuban();        // compile-time regex (NUBAN: 10 digits)
[LoggerMessage(Level = LogLevel.Information, Message = "Transfer {Id} settled in {Ms} ms")]
static partial void LogSettled(ILogger l, string id, long ms);              // no boxing, no string formatting when disabled
.NET PERFORMANCE
one of the fastest managed runtimes, if you let it
allocationsFewer allocations = less GC:structs, Span, pooling.Span and pipelinesParse without copying;System.IO.Pipelines.ArrayPool and ObjectPoolReuse buffers instead ofallocating.source generatorsJSON, regex, logging generated atcompile time.BenchmarkDotNetBenchmarks with statistics andallocation counts.dotnet-trace, dotnet-countersProduction diagnostics and flamegraphs.
swipe the figure sideways, or tap expand for full screen
1/4
allocation-aware code
Measured in part 2: 10M structs allocated nothing where classes allocated 240 MB. Hot paths in ASP.NET Core are written to allocate as little as possible.
allocate lessmeasured 240 MB vs 0