Лучший способ измерить время выполнения фрагмента Python

Я хочу сравнить время выполнения двух фрагментов и посмотреть, какой из них быстрее. Итак, мне нужен точный метод измерения времени выполнения моих фрагментов Python.

Я уже пытался использовать time.time(), time.process_time(), time.perf_counter_ns(), а также timeit.timeit(), но со всеми из них у меня возникают одни и те же проблемы. То есть: когда я использую любой из вышеперечисленных методов для измерения времени выполнения ТОГО ЖЕ фрагмента, он возвращает другое значение каждый раз, когда я его запускаю. И эта вариация несколько значительна, поскольку я не могу надежно использовать их для сравнения разницы во времени выполнения двух фрагментов кода.

В качестве примера я запускаю следующий код в своем коллабе Google:

import time
t1 = time.perf_counter()
sample_list = []
for i in range(1000000):
  sample_list.append(i)
t2 = time.perf_counter()
print(t2 - t1)

Я запускал выше код 10 раз, и разница в моих результатах составляет около 50% (минимальное значение = 0,14, максимальное значение = 0,28).

Любые альтернативы?

timeit запускает сниппет много раз (по умолчанию 1 миллион). Если это бит кода, связанный с процессором, он должен быть одинаковым для всех прогонов. Я замечаю дрейф < 10%. Если делать ввод-вывод, это другая история. У вас есть пример, который мы могли бы попробовать?
tdelaney 18.11.2022 23:15

Термин, который вы ищете, — профилирование: stackoverflow.com/questions/582336/…

Random Davis 18.11.2022 23:20

Я добавил пример, который я запускаю прямо сейчас.

Mohammad M Faghih 18.11.2022 23:23

Google colab является сбивающим с толку фактором. Вы работаете на сервере со многими соавторами. Анализ производительности следует проводить в как можно более строго контролируемой среде. Даже ноутбук с разной тактовой частотой может быть проблемой.

tdelaney 19.11.2022 04:18
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
5
4
168
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Время выполнения данного фрагмента кода почти всегда будет разным при каждом его запуске. Большинство инструментов, доступных для профилирования одной функции/фрагмента кода, учитывают это и запускают код несколько раз, чтобы обеспечить среднее время выполнения. Причина этого в том, что на вашем компьютере запущены другие процессы, а ресурсы не всегда распределяются одинаково, поэтому невозможно контролировать каждую переменную, чтобы вы получали одинаковое время выполнения для каждого запуска.

Один из самых простых способов профилирования данной функции или короткого фрагмента кода — использование «волшебной» команды %timeit в ipython. Пример:

>>> %timeit 1 + 1
8.41 ns ± 0.0181 ns per loop (mean ± std. dev. of 7 runs, 100,000,000 loops each)

Это также позволяет вам вводить многострочный блок кода, если вы используете %%timeit вместо %timeit.

Библиотеку timeit можно использовать независимо, но часто ее проще использовать в интерактивном сеансе ipython.

Дополнительные ресурсы:

timeit также дает разные результаты при одних и тех же условиях (один и тот же фрагмент выполняется одинаковое количество раз). Если нет надежного метода измерения времени выполнения фрагмента, как мы действительно хотим доказать, что один код быстрее другого при оптимизации? Я помню видео на YouTube, сравнивающее время выполнения факториальной функции при расчете на основе рекурсии и циклов. Ютубер использовал метод time.time() и завершил цикл быстрее. Затем я попробовал свою систему и обнаружил, что рекурсия работает быстрее.

Mohammad M Faghih 18.11.2022 23:28

Если нет статистически значимой разницы между временем выполнения, возвращаемым timeit для двух разных реализаций, выполняющих одну и ту же цель, вам следует просто выбрать ту, которая более читабельна/понятнее. Различия в версии Python и в том, где вы запускаете данную программу, могут привести к некоторым различиям, которые вы никогда не устраните полностью. Это справедливо для любого языка программирования.

dskrypa 18.11.2022 23:32

Кроме того, time.time() не следует использовать для измерения времени выполнения чего-либо. Не гарантируется получение точных значений в случае високосных секунд и т.п. Для этого лучше использовать time.montotonic().

dskrypa 19.11.2022 01:37

Спасибо за отзыв. Я где-то читал, что отключение сборки мусора также помогает увеличить точность измерения времени выполнения.

Mohammad M Faghih 19.11.2022 02:44

Другие вопросы по теме