Courses/C#/Performance Profiling

    Performance Profiling & Benchmarking (BenchmarkDotNet)

    Measure before you optimise. Use BenchmarkDotNet for precise benchmarks, and diagnostics tools for production profiling.

    What You'll Learn

    • • Benchmark with BenchmarkDotNet — memory and speed analysis
    • • Compare collection types, string operations, and LINQ vs loops
    • • Use Stopwatch, Activity, and EventCounters for profiling
    • • Read benchmark results and make data-driven decisions

    🏎️ Real-World Analogy

    BenchmarkDotNet is like a professional race track with timing equipment — controlled conditions, multiple laps, statistical analysis. Stopwatch is like timing yourself with a phone — quick but imprecise. EventCounters are like a car's dashboard gauges — real-time metrics in production. Never optimise based on gut feeling — always measure first.

    BenchmarkDotNet — String Operations

    Always run benchmarks in Release mode. BenchmarkDotNet handles warmup, multiple iterations, and statistical analysis — giving you reliable results with memory tracking.

    String Concatenation Benchmark

    Compare string concatenation, StringBuilder, and String.Join performance.

    Try it Yourself »
    C#
    using BenchmarkDotNet.Attributes;
    using BenchmarkDotNet.Running;
    using System.Text;
    
    // Run benchmarks: dotnet run -c Release
    // NEVER benchmark in Debug mode — JIT optimizations are disabled
    
    [MemoryDiagnoser]          // Track memory allocations
    [RankColumn]               // Show ranking
    public class StringBenchmarks
    {
        private readonly string[] _words = Enumerable
            .Range(0, 1000)
            .Select(i => $"word{i}")
            .ToArray();
    
        // ❌ String concatenation — O(n²) allocations
    ...

    Collection Performance Comparison

    Choosing the right collection type can mean 1,000x performance difference. Benchmark lookups across List, HashSet, Dictionary, and Array. Compare LINQ, for loops, and Span for iteration.

    Collection & Iteration Benchmarks

    Benchmark lookup and summation across List, HashSet, Dictionary, Span, and LINQ.

    Try it Yourself »
    C#
    using BenchmarkDotNet.Attributes;
    
    [MemoryDiagnoser]
    public class CollectionBenchmarks
    {
        private List<int> _list = null!;
        private HashSet<int> _hashSet = null!;
        private Dictionary<int, string> _dict = null!;
        private int[] _array = null!;
    
        [GlobalSetup]
        public void Setup()
        {
            _array = Enumerable.Range(0, 10_000).ToArray();
            _list = _array.ToList();
            _hashSet = _array.ToHashSet();
            _dict = _array.ToDictionary(x => x, x => $"item_{x}");
        }
    
    ...

    Production Diagnostics

    For production profiling, use Stopwatch for quick measurements, Activity for distributed tracing, and EventCounters for lightweight real-time metrics.

    Stopwatch, Activity & EventCounters

    Profile production code with timing, tracing, and custom metrics.

    Try it Yourself »
    C#
    using System.Diagnostics;
    
    // Stopwatch — quick ad-hoc timing
    public class PerformanceHelper
    {
        // Simple timing wrapper
        public static async Task<(T Result, TimeSpan Elapsed)> MeasureAsync<T>(
            Func<Task<T>> action)
        {
            var sw = Stopwatch.StartNew();
            var result = await action();
            sw.Stop();
            return (result, sw.Elapsed);
        }
    
        // Usage
        public static async Task Demo()
        {
            var (users, elapsed) = await MeasureAsync(
                async (
    ...

    Pro Tip

    Use [MemoryDiagnoser] on every benchmark. Memory allocation (GC pressure) often matters more than raw speed. A method that's 2x faster but allocates 10x more memory may perform worse in production under load.

    Common Mistakes

    • • Benchmarking in Debug mode — JIT doesn't optimise, results are meaningless
    • • Micro-optimising code that runs once — focus on hot paths and loops
    • • Using DateTime.Now for timing — it's not monotonic; use Stopwatch

    Lesson Complete!

    You've mastered performance profiling and benchmarking. You're now ready for the Final Project — build an enterprise-grade C# application!

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service