Как профилировать мой код? - PullRequest
20 голосов
/ 15 июня 2010

Я хочу знать, как профилировать мой код.

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

У меня большой код, и он занимает так много времени, поэтому я хочу профилировать и увеличить его скорость. Я не написал свой код в методе, между ними мало, но не полностью. У меня нет никакого основного в моем коде. Я хочу знать, как использовать профилирование. Я ищу пример или пример кода о том, как профилировать.

Я попробовал psyco, то есть просто добавил две строки вверху моего кода:

import psyco
psyco.full()

Это правильно? Это не показало никакого улучшения. Любой другой способ ускорить, пожалуйста, предложите.

Ответы [ 3 ]

66 голосов
/ 18 июня 2010

Стандартный ответ на этот вопрос - использовать cProfile .

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

Вместо этого вы можете попробовать то, что здесь называется другой плакат Монте-Карло Профилирование . Цитировать другой ответ :

Если вы спешите и можете вручную прервать вашу программу под отладчик пока он субъективно медленно, есть простой способ найти проблемы с производительностью.

Просто остановите это несколько раз, и каждый время посмотрим на стек вызовов. Если есть какой-то код, который тратит впустую процент времени, 20% или 50% или что бы то ни было, это вероятность того, что вы поймете это в акте на каждом образец. Так что это примерно процент образцов, на которых вы увидим это. Нет образованных догадки требуется. Если у вас есть угадайте, в чем проблема, это докажет или опровергнет это.

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

Предостережение: программисты склонны скептически относится к этой технике, если они использовали это сами. Они будут говорят, что профилировщики дают вам это информация, но это верно только в том случае, если они пробуют весь стек вызовов. Графики вызовов не дают вам то же самое информация, потому что 1) они не Подводя итог на уровне обучения, и 2) они дают запутанные резюме при наличии рекурсии. Oни также скажу, что это работает только на игрушку программы, когда на самом деле это работает на любая программа, и, кажется, работает лучше в больших программах, потому что у них, как правило, больше проблем с найти [ выделение добавлено ].

Это не ортодоксально, но я очень успешно использовал его в проекте, где профилирование с использованием cProfile не давало мне полезного вывода.

Лучшее в этом то, что это очень легко сделать в Python. Просто запустите скрипт Python в интерпретаторе, нажмите [Control-C], отметьте трассировку и повторите несколько раз.

18 голосов
/ 07 марта 2012

Редактировать:

Этот ответ был реализован в https://github.com/campos-ddc/cprofile_graph

Профилирование с помощью cProfile

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

cProfile - один из наиболее часто используемых профилировщиков Python, и хотя он очень мощный, стандартный вывод текста несколько скучнее.Здесь я покажу вам, как проще использовать cProfile в вашем приложении.

Существует два распространенных способа использования cProfile: вы можете использовать его как команду в приглашении для профилирования данного модуля, или выможете использовать его в своем коде для профилирования определенных фрагментов кода.

Профилирование модуля

Чтобы использовать cProfile для профилирования всего модуля, просто введите в командной строке следующую команду:

python -m cProfile -o output_filename.pstats path/to/script arg1 arg2

Это запустит ваш модуль с заданными аргументами (они необязательны) и выведет вывод в файл output_filename.pstats.

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

Профилирование изнутри

Иногда вы не хотите профилироватьвесь модуль, всего несколько строк.

Для этого вам нужно добавить некоторый код в ваш модуль.

Прежде всего:

import cProfile

А потом тыможет заменить любой сегмент кода следующим:

cProfile.runctx('Your code here', globals(), locals(), 'output_file')

Например, вот тест до и после профилирования:

import unittest

class Test(unittest.TestCase):

    def testSomething(self):
        self.DoSomethingIDontCareAbout()

        param = 'whatever'
        self.RunFunctionIThinkIsSlow(param)

        self.AssertSomeStuff() # This is after all, a test

После:

import unittest
import cProfile

class Test(unittest.TestCase):

    def testSomething(self):
        self.DoSomethingIDontCareAbout()

        param = 'whatever'
        cProfile.runctx(
            'self.RunFunctionIThinkIsSlow(param)',
            globals(),
            locals(),
            'myProfilingFile.pstats'
        )

        self.AssertSomeStuff() # This is after all, a test

Преобразование файла pstats в график

Чтобы преобразовать файл профилирования в график, вам потребуется несколько вещей:

  • gprof2dot : Этот модульпреобразует ваш вывод в файл dot , стандартный формат файла для описания графиков.
  • GraphViz : превращает ваш файл dot вimage.

После того, как вы скачали gprof2dot и установили GraphViz , введите в командной строке следующую команду:

python gprof2dot -f pstats myProfileFile | dot -Tpng -o image_output.png

Возможно, вынеобходимо использовать полный путь для gprof2dot и / или dot , или вы можете добавить их в переменную PATH env.

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

results example

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

  • На каждом узле вы можете видеть, какой процент от общего времени выполнения использует эта функция и сколько раз онабыл вызван.

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

Примечание: проценты не всегда будут составлять до 100%, особенно в тех разделах кода, которые ссылаются на код C ++, который не будет профилирован.Кроме того, cProfile не сможет определить, что вызывается из оператора «eval», поэтому вы можете увидеть некоторые скачки на графике.

6 голосов
/ 18 июня 2010

Использование cProfile .Вы можете использовать его из командной строки и передать свой модуль в качестве параметра, поэтому вам не нужен метод main.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...