Вопрос-Ответ

How do I profile a Python script?

Как мне профилировать скрипт на Python?

Project Euler и другие конкурсы по программированию часто требуют максимального времени для запуска или люди хвастаются тем, как быстро работает их конкретное решение. В Python иногда подходы несколько запутанны - например, добавление временного кода в __main__.

Какой хороший способ определить, сколько времени требуется для запуска программы на Python?

Переведено автоматически
Ответ 1

В Python есть профилировщик с именем cProfile. Он не только показывает общее время выполнения, но и умножает время выполнения каждой функции в отдельности и сообщает вам, сколько раз вызывалась каждая функция, что упрощает определение того, где вам следует провести оптимизацию.

Вы можете вызвать его из своего кода или из интерпретатора, вот так:

import cProfile
cProfile.run('foo()')

Еще более полезным является вызов cProfile при запуске скрипта:

python -m cProfile myscript.py

Или при запуске модуля:

python -m cProfile -m mymodule

Чтобы сделать это еще проще, я создал небольшой пакетный файл под названием "profile.bat":

python -m cProfile %1

Итак, все, что мне нужно сделать, это запустить:

profile euler048.py

И я получаю это:

1007 function calls in 0.061 CPU seconds

Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.061 0.061 <string>:1(<module>)
1000 0.051 0.000 0.051 0.000 euler048.py:2(<lambda>)
1 0.005 0.005 0.061 0.061 euler048.py:2(<module>)
1 0.000 0.000 0.061 0.061 {execfile}
1 0.002 0.002 0.053 0.053 {map}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler objects}
1 0.000 0.000 0.000 0.000 {range}
1 0.003 0.003 0.003 0.003 {sum}

РЕДАКТИРОВАТЬ: Обновлена ссылка на хороший видеоресурс из PyCon 2013 под названием
Профилирование Python

Также на YouTube.

Ответ 2

Некоторое время назад я создал pycallgraph который генерирует визуализацию из вашего кода на Python. Редактировать: я обновил пример для работы с 3.3, последней версией на момент написания статьи.

После pip install pycallgraph и установки GraphViz вы можете запустить его из командной строки:

pycallgraph graphviz -- ./mypythonscript.py

Или вы можете профилировать определенные части вашего кода:

from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput

with PyCallGraph(output=GraphvizOutput()):
code_to_profile()

Любой из этих способов сгенерирует pycallgraph.png файл, подобный изображению ниже:

введите описание изображения здесь

Ответ 3

Стоит отметить, что использование профилировщика работает (по умолчанию) только в основном потоке, и вы не получите никакой информации из других потоков, если будете их использовать. Это может вызвать некоторые затруднения, поскольку совершенно не упоминается в документации по профилировщику.

If you also want to profile threads, you'll want to look at the threading.setprofile() function in the docs.

You could also create your own threading.Thread subclass to do it:

class ProfiledThread(threading.Thread):
# Overrides threading.Thread.run()
def run(self):
profiler = cProfile.Profile()
try:
return profiler.runcall(threading.Thread.run, self)
finally:
profiler.dump_stats('myprofile-%d.profile' % (self.ident,))

and use that ProfiledThread class instead of the standard one. It might give you more flexibility, but I'm not sure it's worth it, especially if you are using third-party code which wouldn't use your class.

Ответ 4

Python wiki - отличная страница для профилирования ресурсов: http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code

как и документы по python: http://docs.python.org/library/profile.html

как показал Крис Лоулор, cProfile - отличный инструмент, который можно легко использовать для вывода на экран:

python -m cProfile -s time mine.py <args>

или в файл:

python -m cProfile -o output.file mine.py <args>

PS> Если вы используете Ubuntu, обязательно установите python-profile

apt-get install python-profiler 

При выводе в файл вы можете получить красивые визуализации, используя следующие инструменты

PyCallGraph: инструмент для создания образов графиков вызовов
установить:

 pip install pycallgraph

выполнить:

 pycallgraph mine.py args

Вид:

 gimp pycallgraph.png

Вы можете использовать все, что вам нравится, для просмотра файла png, я использовал gimp
К сожалению, я часто получаю

точка: график слишком велик для растровых изображений cairo-renderer. Масштабирование на 0,257079 для соответствия

что делает мои изображения неприемлемо маленькими. Поэтому я обычно создаю svg-файлы:

pycallgraph -f svg -o pycallgraph.svg mine.py <args>

PS> обязательно установите graphviz (который предоставляет программу dot):

pip install graphviz

Альтернативное построение графиков с использованием gprof2dot через @maxy / @quodlibetor :

pip install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg
python performance