Ответ
Для точного измерения производительности в .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 показывают не только общее время, но и что именно его тратит: методы, вызовы БД, сборка мусора. Это инструмент для поиска узких мест, а не для точечного измерения.
Ответ 18+ 🔞
А, ну ты хочешь замерить производительность в .NET, да? Ну, брат, это не просто DateTime.Now отнять, тут мозги надо включать, а то наебнёшься на ровном месте. Сейчас разжую.
Смотри, если тебе просто прикинуть, не оторвало ли твоему методу руки, то Stopwatch — твой быстрый друг. Но друг, блядь, подставной, если ты не знаешь, как им пользоваться.
using System.Diagnostics;
// Не создавай просто new Stopwatch() и не вызывай Start()! Это для лохов.
// StartNew — это сразу и создание, и старт. Чисто, аккуратненько.
var sw = Stopwatch.StartNew();
// Тут твой код, который, возможно, жрёт ресурсы как не в себя
DoSomeWork();
sw.Stop();
Console.WriteLine($"Время выполнения: {sw.ElapsedMilliseconds} мс");
Console.WriteLine($"Точное время: {sw.ElapsedTicks} тиков");
Но запомни раз и навсегда: один запуск — это хуйня, а не измерение. JIT-компилятор может в первый раз подумать, GC может внезапно почистить память и всё испортить. Запускай в цикле, тысяч сто раз, первый результат выкидывай нахуй, а остальные усредняй. Иначе получишь цифры, которые только в унитазе смотреть.
А теперь, если ты хочешь не прикинуть, а точно знать, где у тебя бутылочное горлышко, то забудь про эти ручные замеры, как страшный сон. Твой новый бог — BenchmarkDotNet. Это, блядь, целая наука, упакованная в NuGet.
Ставишь пакет и делаешь вот такую красоту:
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
[MemoryDiagnoser] // Этот атрибут — святое. Он покажет, сколько памяти твой код сожрал.
[RankColumn] // Ранжирование, чтобы сразу видно было, кто быстрее, а кто тормоз.
public class StringBenchmark
{
private string data = "Hello, World!";
[Benchmark] // Пометил метод — и он уже в сетке бенчмарка.
public string ToUpperInvariant() => data.ToUpperInvariant();
[Benchmark]
public string ToUpper() => data.ToUpper();
}
public class Program
{
public static void Main(string[] args) => BenchmarkRunner.Run<StringBenchmark>();
}
Самое главное — запускай это в Release-конфигурации и без отладчика, придурок! Иначе JIT-компилятор будет делать неоптимальный код, и все твои замеры полетят в пизду. После запуска получишь таблицу, где будет среднее время, стандартное отклонение (чтобы видеть, насколько результаты пляшут) и, о чудо, аллокации памяти. Прямо увидишь, какой метод не только медленный, но ещё и мусора после себя кучу оставляет.
Ну и высший пилотаж — это профилировщики. dotTrace, встроенные в Visual Studio Diagnostic Tools или тот же PerfView от Microsoft. Это уже не просто "сколько времени", а "на что именно это время потратилось". Ты увидишь дерево вызовов, поймёшь, что 80% времени твоё приложение жрёт не твой алгоритм, а, например, ходит в базу данных или, прости господи, в цикле создаёт новые строки.
Короче, алгоритм такой:
- Быстрая прикидка на глаз —
Stopwatchс умом. - Точный, воспроизводимый замер —
BenchmarkDotNet. Без вариантов. - Поиск конкретной причины тормозов — профилировщик.
Выбирай по задаче, а то будешь, как дурак, DateTime мерить и удивляться, почему в продакшене всё встало колом.