Project Euler и другие конкурсы по кодированию часто имеют максимальное время для запуска, или люди хвастаются тем, насколько быстро работает их конкретное решение. В Python иногда подходы несколько хитры - например, добавление временного кода в __main__
.
Как правильно определить, сколько времени занимает запуск программы на Python?
python
performance
profiling
time-complexity
Крис Лоулор
источник
источник
Ответы:
Python включает в себя профилировщик cProfile . Он не только показывает общее время выполнения, но и время каждой функции в отдельности, а также сообщает, сколько раз была вызвана каждая функция, что позволяет легко определить, где вы должны выполнить оптимизацию.
Вы можете вызвать его из своего кода или из интерпретатора, например так:
Еще полезнее, что вы можете вызвать cProfile при запуске скрипта:
Чтобы сделать это еще проще, я создал небольшой пакетный файл с именем 'profile.bat':
Так что все, что мне нужно сделать, это запустить:
И я получаю это:
РЕДАКТИРОВАТЬ: Обновленная ссылка на хороший видео-ресурс из PyCon 2013 под названием Python Profiling
Также через YouTube .
источник
python -m cProfile -o <out.profile> <script>
), RunSnakeRun , вызывается какrunsnake <out.profile>
бесценный.cprofile
по - прежнему рекомендуется болееprofile
.Некоторое время назад я сделал,
pycallgraph
который генерирует визуализацию из вашего кода Python. Изменить: я обновил пример для работы с 3.3, последний выпуск на момент написания.После
pip install pycallgraph
установки и установки GraphViz вы можете запустить его из командной строки:Или вы можете профилировать отдельные части вашего кода:
Любой из них создаст
pycallgraph.png
файл, похожий на изображение ниже:источник
Traceback (most recent call last): /pycallgraph.py", line 90, in generate output.done() File "/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py", line 94, in done source = self.generate() File "/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py", line 143, in generate indent_join.join(self.generate_attributes()), File "/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py", line 169, in generate_attributes section, self.attrs_from_dict(attrs), ValueError: zero length field name in format
sudo apt-get install graphviz
.Стоит отметить, что использование профилировщика работает (по умолчанию) только в основном потоке, и вы не получите никакой информации из других потоков, если будете их использовать. Это может быть немного затруднительно, поскольку это совершенно не упоминается в документации профилировщика .
Если вы также хотите профилировать потоки, вы должны посмотреть на
threading.setprofile()
функцию в документах.Вы также можете создать свой собственный
threading.Thread
подкласс для этого:и использовать этот
ProfiledThread
класс вместо стандартного. Это может дать вам больше гибкости, но я не уверен, что оно того стоит, особенно если вы используете сторонний код, который не будет использовать ваш класс.источник
target
функцию Thread , то есть то, чтоthreading.Thread.run()
выполняет вызов. Но, как я сказал в ответе, вероятно, не стоит делать подкласс Thread, поскольку любой сторонний код не будет его использовать, а вместо этого использоватьthreading.setprofile()
.Python Wiki - отличная страница для профилирования ресурсов: http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code
как и документы по питону: http://docs.python.org/library/profile.html
Крис Лоулор показывает, что cProfile - отличный инструмент, который можно легко использовать для печати на экране:
или в файл:
PS> Если вы используете Ubuntu, обязательно установите python-профиль
Если вы выводите в файл, вы можете получить хорошую визуализацию, используя следующие инструменты
PyCallGraph: инструмент для создания изображений графа вызовов
.
запустить:
Посмотреть:
Вы можете использовать все, что вам нравится, чтобы просмотреть файл PNG, я использовал GIMP
К сожалению, я часто получаю
точка: график слишком велик для растровых изображений каир-рендерера. Масштабирование по 0,257079, чтобы соответствовать
что делает мои изображения необычайно маленькими. Поэтому я обычно создаю SVG-файлы:
PS> Обязательно установите graphviz (который предоставляет программа dot):
Альтернативный график с использованием gprof2dot через @maxy / @quodlibetor:
источник
@ Комментарий Макси к этому ответу выручил меня настолько, что я думаю, что он заслуживает своего собственного ответа: у меня уже были файлы, сгенерированные cProfile .pstats, и я не хотел перезапускать вещи с pycallgraph, поэтому я использовал gprof2dot , и получил довольно SVGs:
и БЛАМ!
Он использует точку (то же самое, что и pycallgraph), поэтому вывод выглядит аналогично. У меня создается впечатление, что gprof2dot теряет меньше информации:
источник
pwd
/gprof2dot/gprof2dot.py $ HOME / bin (или использовать ln -s $ PWD / gprof2dot / gprof2dot.py ~ / bin в большинстве оболочек - серьезный акцент используется в качестве форматирования в первой версия).ln
неправильный порядок аргументов почти каждый раз.Я столкнулся с удобным инструментом под названием SnakeViz при исследовании этой темы. SnakeViz - это веб-инструмент для визуализации профилирования. Это очень легко установить и использовать. Обычный способ, которым я использую его, - это сгенерировать файл статистики с помощью,
%prun
а затем выполнить анализ в SnakeViz.Основным методом, который используется, является диаграмма Sunburst, как показано ниже, в которой иерархия вызовов функций организована в виде слоев дуг и информации о времени, закодированных по их угловым значениям ширины.
Лучше всего, вы можете взаимодействовать с графиком. Например, чтобы увеличить масштаб, можно щелкнуть мышью по дуге, и дуга и ее потомки будут увеличены до новых солнечных лучей, чтобы отобразить больше деталей.
источник
Самый простой и быстрый способ найти, куда все время идет.
Рисует круговую диаграмму в браузере. Самая большая часть - это проблемная функция. Очень просто.
источник
Я думаю, что
cProfile
это хорошо для профилирования, а такжеkcachegrind
для визуализации результатов.pyprof2calltree
Между ручками преобразования файлов.Чтобы установить необходимые инструменты (по крайней мере, в Ubuntu):
Результат:
источник
brew install qcachegrind
и substitude каждыйkcachegrind
сqcachegrind
в описании для успешного профилирования.export QT_X11_NO_MITSHM=1
Также стоит упомянуть программу просмотра дампа cProfile с графическим интерфейсом RunSnakeRun . Это позволяет вам сортировать и выбирать, тем самым увеличивая соответствующие части программы. Размеры прямоугольников на картинке пропорциональны затраченному времени. Если вы наведите курсор мыши на прямоугольник, он выделит этот вызов в таблице и повсюду на карте. Когда вы дважды щелкаете по прямоугольнику, он увеличивает эту часть. Он покажет вам, кто вызывает эту часть и что эта часть вызывает.
Описательная информация очень полезна. Он показывает вам код для этого бита, который может быть полезен, когда вы имеете дело со встроенными вызовами библиотеки. Он говорит вам, какой файл и в какой строке найти код.
Также хочу отметить, что ОП сказал «профилирование», но, похоже, он имел в виду «выбор времени». Имейте в виду, что программы будут работать медленнее при профилировании.
источник
Недавно я создал тунца для визуализации Python во время выполнения и импорта профилей; это может быть полезно здесь.
Установить с
Создать профиль времени выполнения
или профиль импорта (требуется Python 3.7+)
Тогда просто запустите тунца на файл
источник
Хорошим модулем профилирования является line_profiler (вызывается с использованием скрипта kernprof.py). Это можно скачать здесь .
Насколько я понимаю, cProfile предоставляет только информацию об общем времени, потраченном на каждую функцию. Таким образом, отдельные строки кода не рассчитаны. Это проблема научных вычислений, поскольку часто одна строка может занимать много времени. Кроме того, насколько я помню, cProfile не улавливал время, которое я проводил, скажем, в numpy.dot.
источник
pprofile
line_profiler
(уже представлен здесь) также вдохновилpprofile
, который описывается как:Он обеспечивает линейную гранулярность, так как
line_profiler
является чистым Python, может использоваться как отдельная команда или модуль и может даже генерировать файлы в формате callgrind, которые могут быть легко проанализированы с помощью[k|q]cachegrind
.vprof
Существует также vprof , пакет Python, описанный как:
источник
Есть много отличных ответов, но они либо используют командную строку, либо какую-то внешнюю программу для профилирования и / или сортировки результатов.
Я действительно упустил какой-то способ, которым я мог бы использовать в своей IDE (eclipse-PyDev), не касаясь командной строки и не устанавливая что-либо. Так и здесь.
Профилирование без командной строки
Смотрите документы или другие ответы для получения дополнительной информации.
источник
После ответа Джо Шоу о том, что многопоточный код не работает
runcall
должным образом , я понял, что метод в cProfile просто выполняетself.enable()
иself.disable()
вызывает вызов профилируемой функции, так что вы можете просто сделать это самостоятельно и получить любой код, который вы хотите использовать с минимальное вмешательство в существующий код.источник
cprofile.py
исходный код показывает, что это именно то , чтоruncall()
делает. Точнее говоря, после создания экземпляра Profile с помощьюprof = cprofile.Profile()
, немедленно позвонитеprof.disable()
, а затем просто добавьтеprof.enable()
иprof.disable()
обзвоните раздел кода, который вы хотите профилировать.В Виртаале источнике есть очень полезный класс и декоратор , который может сделать профилирование (даже для конкретных методов / функций) очень легко. Выходные данные можно просмотреть очень удобно в KCacheGrind.
источник
cProfile отлично подходит для быстрого профилирования, но большую часть времени он заканчивался для меня ошибками. Функция runctx решает эту проблему, правильно инициализируя окружение и переменные, надеясь, что это может быть полезно для кого-то:
источник
Если вы хотите создать накопительный профилировщик, то есть запустить функцию несколько раз подряд и посмотреть сумму результатов.
Вы можете использовать этот
cumulative_profiler
декоратор:это специфично для python> = 3.6, но вы можете удалить
nonlocal
его для более старых версий.пример
профилирование функции
baz
baz
побежал 5 раз и напечатал это:указав количество раз
источник
Только для терминала (и самое простое) решение, в случае если все эти модные интерфейсы пользователя не могут быть установлены или запущены: полностью
игнорировать
cProfile
и заменить его на тоpyinstrument
, что будет собирать и отображать дерево вызовов сразу после выполнения.Установка:
Профиль и результат отображения:
Работает с python2 и 3.
[РЕДАКТИРОВАТЬ] Документация API, для профилирования только часть кода, можно найти здесь .
источник
Мой способ - использовать yappi ( https://github.com/sumerc/yappi ). Это особенно полезно в сочетании с RPC-сервером, на котором (даже только для отладки) вы регистрируете метод для запуска, остановки и печати данных профилирования, например, таким образом:
Затем, когда ваша программа заработает, вы можете в любой момент запустить профилировщик, вызвав
startProfiler
метод RPC, и вывести информацию о профилировании в файл журнала, вызвавprintProfiler
(или изменив метод rpc, чтобы вернуть его вызывающей стороне), и получить такой вывод:Это может быть не очень полезно для коротких сценариев, но помогает оптимизировать процессы серверного типа, особенно с учетом того, что
printProfiler
метод может вызываться несколько раз с течением времени для профилирования и сравнения, например, различных сценариев использования программы.В новых версиях yappi будет работать следующий код:
источник
def printProfiler(): if not yappi_available: return stats = yappi.get_func_stats() stats.print_all(columns={0:("name",90), 1:("ncall", 5), 2:("tsub", 8), 3:("ttot", 8), 4:("tavg",8)})
(ОК после попытки пару раз вставить блок кода в оставленный мной комментарий. Это невероятно сложно для ориентированного на программирование сайта вопросов и ответов. )Новый инструмент для обработки профилей в Python - это PyVmMonitor: http://www.pyvmmonitor.com/
У этого есть некоторые уникальные особенности, такие как
Примечание: он коммерческий, но бесплатный для открытого источника.
источник
gprof2dot_magic
Магическая функция для
gprof2dot
профилирования любого оператора Python в виде графа DOT в JupyterLab или Jupyter Notebook.Репозиторий GitHub: https://github.com/mattijn/gprof2dot_magic
установка
Убедитесь, что у вас есть пакет Python
gprof2dot_magic
.Его зависимости
gprof2dot
иgraphviz
будут установленыПрименение
Чтобы включить магическую функцию, сначала загрузите
gprof2dot_magic
модульа затем профилировать любой оператор строки как график DOT как таковой:
источник
https://github.com/amoffat/Inspect-Shell
Вы можете использовать это (и ваши наручные часы).
источник
Добавить на https://stackoverflow.com/a/582337/1070617 ,
Я написал этот модуль, который позволяет вам использовать cProfile и легко просматривать его вывод. Больше здесь: https://github.com/ymichael/cprofilev
Также см .: http://ymichael.com/2014/03/08/profiling-python-with-cprofile.html о том, как разобраться в собранной статистике.
источник
Это будет зависеть от того, что вы хотите увидеть из профилирования. Простые метрики времени могут быть предоставлены (bash).
Даже '/ usr / bin / time' может выводить подробные метрики, используя флаг --verbose.
Чтобы проверить показатели времени, предоставляемые каждой функцией, и лучше понять, сколько времени тратится на функции, вы можете использовать встроенный cProfile в python.
Если говорить о более детальных показателях, таких как производительность, время - не единственная метрика. Вы можете беспокоиться о памяти, потоках и т. Д. Параметры
профилирования:
1. line_profiler - еще один профилировщик, используемый для построчного поиска метрик времени.
2. memory_profiler - это инструмент для профилирования использования памяти.
3. куча (из проекта гуппи) Профиль того, как используются объекты в куче.
Вот некоторые из наиболее часто используемых мной. Но если вы хотите узнать больше, попробуйте прочитать эту книгу. Это очень хорошая книга о том, как начать с производительности. Вы можете перейти к более сложным темам об использовании Python, скомпилированных на языке Cython и JIT (Just-in-time).
источник
С таким статистическим профилировщиком, как Остин , не требуется никаких инструментов, а это означает, что вы можете получать данные профилирования из приложения Python просто с
Необработанный вывод не очень полезен, но вы можете направить его в Flamegraph.pl, чтобы получить представление данных пламени на графике пламени, которое дает вам представление о том, где время (измеренное в микросекундах реального времени) тратится.
источник
Для получения быстрой статистики профиля на ноутбуке IPython. Можно встраивать line_profiler и memory_profiler прямо в свои ноутбуки.
Еще один полезный пакет - это Pympler . Это мощный пакет профилирования, который способен отслеживать классы, объекты, функции, утечки памяти и т. Д. Примеры ниже, документы прилагаются.
Возьми!
Загрузите это!
Используй это!
%время
дает:
% timeit
% prun
дает:
% memit
дает:
% lprun
дает:
sys.getsizeof
Возвращает размер объекта в байтах.
asizeof () от pympler
pympler.asizeof может использоваться, чтобы исследовать, сколько памяти потребляют определенные объекты Python. В отличие от sys.getsizeof, asizeof размеров рекурсивно
трекер от пимплера
Отслеживает время жизни функции.
Пакет Pympler состоит из огромного количества высокоуровневых функций для профилирования кода. Все это не может быть рассмотрено здесь. См. Прилагаемую документацию для реализации подробного профиля.
Pympler doc
источник
Также есть статистический профайлер
statprof
. Это профилировщик выборки, поэтому он добавляет минимальные накладные расходы к вашему коду и дает синхронизацию по строкам (а не только по функциям). Он больше подходит для мягких приложений реального времени, таких как игры, но может иметь меньшую точность, чем cProfile.Версия в PyPI старовата, поэтому его можно установить с
pip
помощью указания мерзавцев хранилища :Вы можете запустить его так:
Смотрите также https://stackoverflow.com/a/10333592/320036
источник
Я только что разработал свой собственный профилировщик, вдохновленный pypref_time:
https://github.com/modaresimr/auto_profiler
При добавлении декоратора он покажет дерево трудоемких функций
@Profiler(depth=4, on_disable=show)
пример
Пример вывода
источник
Когда я не являюсь пользователем root на сервере, я использую lsprofcalltree.py и запускаю свою программу следующим образом:
Затем я могу открыть отчет с помощью любого совместимого с callgrind программного обеспечения, такого как qcachegrind
источник