Каковы лучшие практики и инструменты для профилирования и тестирования кода Python?

Возможный дубликат:
Как профилировать мой код?

Каковы лучшие практики и инструменты для профилирования и тестирования кода Python? Любые быстрые победы здесь или рекомендации.

Популярные швы CProfile и несколько замечательных примечаний / ответов ниже, оба являются очень хорошими ответами / учебниками. Проголосуйте, и я выберу лучший через день или два. Спасибо @senderle и @ campos.ddc

Есть ли какие-нибудь идиомы и / или советы по преобразованию кода, чтобы сделать его быстрее, после того, как проблемная область будет найдена?


person Matt Alcock    schedule 23.02.2012    source источник
comment
Отличная ссылка, спасибо Рик. Я проверю это. Есть ли другие идиомы, кроме профилирования?   -  person Matt Alcock    schedule 23.02.2012
comment
Вот быстрая победа.   -  person Mike Dunlavey    schedule 23.02.2012


Ответы (1)


cProfile - классический инструмент профилирования. Основной способ его использования - вот так:

python -m cProfile myscript.py

Здесь я назвал это тестовой программой эталонной реализации написанного мной mersenne twister .

me@mine $ python -m cProfile mersenne.twister.py 
True
True
1000000
         1003236 function calls in 2.163 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    2.163    2.163 <string>:1(<module>)
        1    0.001    0.001    2.162    2.162 mersenne.twister.py:1(<module>)
        3    0.001    0.000    0.001    0.000 mersenne.twister.py:10(init_gen)
  1000014    1.039    0.000    1.821    0.000 mersenne.twister.py:19(extract_number)
        1    0.000    0.000    0.000    0.000 mersenne.twister.py:3(Twister)
     1603    0.766    0.000    0.782    0.000 mersenne.twister.py:33(generate_numbers)
        1    0.000    0.000    0.000    0.000 mersenne.twister.py:4(__init__)
        1    0.317    0.317    2.161    2.161 mersenne.twister.py:42(_test)
        1    0.001    0.001    2.163    2.163 {execfile}
        1    0.000    0.000    0.000    0.000 {len}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
     1608    0.038    0.000    0.038    0.000 {range}

ncalls - количество вызовов функции. tottime - общее время, затраченное на выполнение функции, исключая время, затраченное на вызовы подфункций. percall это tottime / ncalls. cumtime - время, затраченное на выполнение функции, включая время, затраченное на вызовы подфункций. А остальные данные следующие: filename:lineno(func_name).

В большинстве случаев сначала смотрите на ncalls и tottime. Из приведенных выше данных видно, что большая часть времени, затрачиваемого этой программой, приходится на extract_number. Кроме того, мы видим, что extract_number вызывается много (1000014) раз. Так что все, что я могу сделать для ускорения extract_number, значительно ускорит выполнение этого тестового кода. Если он дает мне микросекунду, тогда усиление будет умножено на 1000014, что даст усиление на полную секунду.

Тогда я должен работать над generate_numbers. Прибыль там не будет иметь большого значения, но она все равно может быть значительной, и, поскольку эта функция сжигает еще 0,7 секунды, есть некоторая выгода.

Это должно дать вам общее представление. Однако обратите внимание, что число tottime может иногда вводить в заблуждение, например, в случаях рекурсии.

person senderle    schedule 23.02.2012
comment
Спасибо, отправитель, есть какие-нибудь советы о том, как интерпретировать результаты и действовать с ними? - person Matt Alcock; 23.02.2012
comment
@MattAlcock Вы можете ознакомиться с официальной документацией python по профилированию: docs.python.org/library /profile.html - person ; 23.02.2012