Есть ли простой способ проверить скрипт python?
обычно я использую команду оболочки time
. Моя цель-проверить, являются ли данные небольшим, средним, большим или очень большим набором, сколько времени и памяти будет использоваться.
любые инструменты для linux или просто python, чтобы сделать это?
6 ответов:
посмотреть timeit,профилировщик python и pycallgraph.
timeit
def test(): """Stupid test function""" lst = [] for i in range(100): lst.append(i) if __name__ == '__main__': import timeit print(timeit.timeit("test()", setup="from __main__ import test"))
по существу, вы можете передать его код python в качестве строкового параметра, и он будет выполняться в указанное количество раз и выводит время выполнения. Важные биты из документов:
timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000)
создать
Timer
экземпляр с заданными заявление,настройка код и таймер казни.... и:
Timer.timeit(number=1000000)
времени выполнение основного утверждения. Это выполняет установку заявление один раз, а затем возвращает время, необходимое для выполнения основных заявление ряд время, измеренное в секундах как поплавок. Аргумент-это число раз через цикл, по умолчанию равное единице миллион. Основной оператор, оператор настройки и функция таймера используемые передаются в конструктор.
Примечание
по умолчанию
timeit
временно выключаетсяgarbage collection
в ходе времени. Преимущество такого подхода заключается в том, что это делает независимые тайминги более сопоставимыми. Этот недостаток что ГС может быть важным компонентом деятельности измеряемая функция. Если это так, GC может быть повторно включен в качестве первого заявление в настройка строку. Например:
timeit.Timer('for i in xrange(10): oct(i)', 'gc.enable()').timeit()
профилирования
профилирование даст вам много более детальное представление о том, что происходит. Вот "мгновенный пример" от официальные документы:
import cProfile import re cProfile.run('re.compile("foo|bar")')
что даст вам:
197 function calls (192 primitive calls) in 0.002 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.001 0.001 <string>:1(<module>) 1 0.000 0.000 0.001 0.001 re.py:212(compile) 1 0.000 0.000 0.001 0.001 re.py:268(_compile) 1 0.000 0.000 0.000 0.000 sre_compile.py:172(_compile_charset) 1 0.000 0.000 0.000 0.000 sre_compile.py:201(_optimize_charset) 4 0.000 0.000 0.000 0.000 sre_compile.py:25(_identityfunction) 3/1 0.000 0.000 0.000 0.000 sre_compile.py:33(_compile)
обе эти модули должны дать вам представление о том, где искать узкие места.
кроме того, чтобы справиться с выходом
profile
посмотри этот постpycallgraph
модуль использует graphviz для создания callgraphs, таких как следующее:
вы можете легко увидеть, какие пути используются больше всего времени по цвету. Вы можете либо создать их с помощью API pycallgraph, либо с помощью упакованного скрипта:
накладные расходы довольно значительны. Таким образом, для уже длительных процессов создание графика может занять некоторое время.pycallgraph graphviz -- ./mypythonscript.py
Я использую простой декоратор, чтобы время func
def st_time(func): """ st decorator to calculate the total time of a func """ def st_func(*args, **keyArgs): t1 = time.time() r = func(*args, **keyArgs) t2 = time.time() print "Function=%s, Time=%s" % (func.__name__, t2 - t1) return r return st_func
The
timeit
модуль был медленным и странным, поэтому я написал это:def timereps(reps, func): from time import time start = time() for i in range(0, reps): func() end = time() return (end - start) / reps
пример:
import os listdir_time = timereps(10000, lambda: os.listdir('/')) print "python can do %d os.listdir('/') per second" % (1 / listdir_time)
для меня, он говорит:
python can do 40925 os.listdir('/') per second
это примитивный вид бенчмаркинга, но это достаточно хорошо.
Я обычно делаю быстрый
time ./script.py
чтобы увидеть, сколько времени это займет. Это не показывает вам память, хотя, по крайней мере, не по умолчанию. Вы можете использовать/usr/bin/time -v ./script.py
получить много информации, включая использование памяти.
посмотреть нос и на одном из своих плагинов,этот в частности.
после установки, нос-это скрипт в вашем пути, и что вы можете вызвать в каталоге, который содержит некоторые скрипты python:
$: nosetests
это будет выглядеть во всех файлах python в текущем каталоге и будет выполнять любую функцию, которую он распознает как тест: например, он распознает любую функцию со словом test_ в ее имени как A тест.
так что вы можете просто создать скрипт python под названием test_yourfunction.py и написать что-то вроде этого в нем:
$: cat > test_yourfunction.py def test_smallinput(): yourfunction(smallinput) def test_mediuminput(): yourfunction(mediuminput) def test_largeinput(): yourfunction(largeinput)
тогда вы должны бежать
$: nosetest --with-profile --profile-stats-file yourstatsprofile.prof testyourfunction.py
и чтобы прочитать файл профиля, используйте эту строку python:
python -c "import hotshot.stats ; stats = hotshot.stats.load('yourstatsprofile.prof') ; stats.sort_stats('time', 'calls') ; stats.print_stats(200)"
профилировщик памяти для всех ваших потребностей в памяти.
https://pypi.python.org/pypi/memory_profiler
запустите pip install:
pip install memory_profiler
импорт библиотеки:
import memory_profiler
добавьте декоратор к элементу, который вы хотите профилировать:
@profile def my_func(): a = [1] * (10 ** 6) b = [2] * (2 * 10 ** 7) del b return a if __name__ == '__main__': my_func()
выполнить код:
python -m memory_profiler example.py
получить вывод:
Line # Mem usage Increment Line Contents ============================================== 3 @profile 4 5.97 MB 0.00 MB def my_func(): 5 13.61 MB 7.64 MB a = [1] * (10 ** 6) 6 166.20 MB 152.59 MB b = [2] * (2 * 10 ** 7) 7 13.61 MB -152.59 MB del b 8 13.61 MB 0.00 MB return a
примеры взяты из документов, связанных выше.