Как рассчитать время выполнения метода с операциями по 1, 2 и 3 секунды?
C#время выполненияметодыоптимизацияпроизводительность
Что проверяют
Вопрос с подвохом: важен не Stopwatch, а понимание, как время зависит от способа вызова. Хороший ответ начинается со слов «зависит от того, как вызваны операции», дальше идут варианты. Следом обычно показывают код с async без единого await внутри.
Как отвечать
Разберите варианты:
- последовательно и синхронно: три
Thread.Sleepподряд дают около 6 секунд, поток всё это время заблокирован; - последовательные
await:await Op1(); await Op2(); await Op3();сTask.Delayвнутри тоже около 6 секунд, но поток на время ожидания освобождается; - параллельно:
await Task.WhenAll(Op1(), Op2(), Op3())даёт около 3 секунд, время самой долгой операции.Parallel.Invokeс синхронными операциями тоже около 3 секунд, но занимает три потока; - без ожидания: запуск задач без
awaitвернёт управление за миллисекунды, а исключения потеряются; - подвох с async: если в
async-методе стоитThread.Sleep, а настоящегоawaitнет, метод выполнится синхронно прямо при вызове. ТогдаTask.WhenAll(Op1(), Op2(), Op3())снова даст 6 секунд, а компилятор лишь выдаст предупреждение CS1998.
Мерить так:
Stopwatch:Stopwatch.StartNew()иElapsed, либо без аллокацииStopwatch.GetTimestamp()иStopwatch.GetElapsedTime(start)(с .NET 7).DateTime.Nowне подходит: грубое разрешение и зависимость от перевода системных часов;- точность:
Task.DelayиThread.Sleepгарантируют «не меньше», на Windows шаг системного таймера около 15 мс, поэтому 3000 мс легко становятся 3010; - микробенчмарки: для коротких операций BenchmarkDotNet, он делает прогрев и статистику, а одиночный замер вместе с JIT-компиляцией врёт.
Где спотыкаются
Отвечают «6 секунд» без уточнений или сразу пишут код со Stopwatch, не заметив, что суть вопроса в модели выполнения.
Считают, что async сам по себе делает код параллельным. Без реального асинхронного ожидания это обычный синхронный вызов.
Запускают через Task.Run сотню задач с Thread.Sleep. Пул потоков добавляет потоки постепенно, и «параллельный» вариант работает заметно дольше расчётного.