Как измерить производительность (перформанс) кода на C#?

«Как измерить производительность (перформанс) кода на C#?» — вопрос из категории C# Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для точного измерения производительности в .NET недостаточно просто засечь время. Важно учитывать работу сборщика мусора (GC), JIT-компиляцию и оптимизации.

1. Быстрая проверка: System.Diagnostics.Stopwatch Подходит для грубых оценок и замера операций, длящихся миллисекунды и больше.

using System.Diagnostics;

// Всегда используйте StartNew для чистоты измерения
var sw = Stopwatch.StartNew();

// Код, производительность которого нужно измерить
DoSomeWork();

sw.Stop();
Console.WriteLine($"Время выполнения: {sw.ElapsedMilliseconds} мс");
Console.WriteLine($"Точное время: {sw.ElapsedTicks} тиков");

Важно: Запускайте код много раз в цикле, игнорируйте первый "прогревочный" запуск (JIT-компиляция), усредняйте результаты.

2. Профессиональный бенчмаркинг: BenchmarkDotNet Это стандарт де-факто для надежных измерений. Библиотека автоматически решает проблемы с "прогревом", статистикой, сборкой мусора и многопоточностью.

  • Установите пакет: Install-Package BenchmarkDotNet
  • Создайте класс бенчмарка:
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

[MemoryDiagnoser] // Также анализирует выделение памяти (GC)
[RankColumn]     // Добавляет колонку с ранжированием
public class StringBenchmark
{
    private string data = "Hello, World!";

    [Benchmark]
    public string ToUpperInvariant() => data.ToUpperInvariant();

    [Benchmark]
    public string ToUpper() => data.ToUpper();
}

// Запуск в Main
public class Program
{
    public static void Main(string[] args) => BenchmarkRunner.Run<StringBenchmark>();
}

Запуск приложения в конфигурации Release (без отладчика!) выдаст детальную таблицу со средним временем, отклонением и выделенной памятью.

3. Профилировщики (Profilers) Инструменты вроде JetBrains dotTrace, Visual Studio Diagnostic Tools или PerfView показывают не только общее время, но и что именно его тратит: методы, вызовы БД, сборка мусора. Это инструмент для поиска узких мест, а не для точечного измерения.