Профилирование кода в Python

Введение

Примеры

  • 1

    %% timeit и% timeit в IPython

    Конкатенация строки профилирования:

     In [1]: import string
    
    In [2]: %%timeit s=""; long_list=list(string.ascii_letters)*50
      ....: for substring in long_list:
      ....:   s+=substring
      ....:
    1000 loops, best of 3: 570 us per loop
    
    In [3]: %%timeit long_list=list(string.ascii_letters)*50
      ....: s="".join(long_list)
      ....:
    100000 loops, best of 3: 16.1 us per loop
    
     

    Профилирование циклов по итерациям и спискам:

     In [4]: %timeit for i in range(100000):pass
    100 loops, best of 3: 2.82 ms per loop
    
    In [5]: %timeit for i in list(range(100000)):pass
    100 loops, best of 3: 3.95 ms per loop 
  • 0

    функция timeit ()

    Профилирование повторения элементов в массиве

     >>> import timeit
    >>> timeit.timeit('list(itertools.repeat("a", 100))', 'import itertools', number = 10000000)
    10.997665435877963
    >>> timeit.timeit('["a"]*100', number = 10000000)
    7.118789926862576 
  • 0

    командная строка timeit

    Профилирование конкатенации чисел

     python -m timeit "'-'.join(str(n) for n in range(100))"
    10000 loops, best of 3: 29.2 usec per loop
    
    python -m timeit "'-'.join(map(str,range(100)))"
    100000 loops, best of 3: 19.4 usec per loop 
  • 0

    line_profiler в командной строке

    Исходный код с директивой @profile перед функцией, которую мы хотим профилировать:

     import requests
    
    @profile
    def slow_func():
        s = requests.session()
        html=s.get("https://en.wikipedia.org/").text
        sum([pow(ord(x),3.1) for x in list(html)])
    
    for i in range(50):
        slow_func()
    
     

    Использование команды kernprof для расчета профилирования построчно

     $ kernprof -lv so6.py
    
    Wrote profile results to so6.py.lprof
    Timer unit: 4.27654e-07 s
    
    Total time: 22.6427 s
    File: so6.py
    Function: slow_func at line 4
    
    Line #      Hits         Time  Per Hit   % Time  Line Contents
    ==============================================================
         4                                           @profile
         5                                           def slow_func():
         6        50        20729    414.6      0.0      s = requests.session()
         7        50     47618627 952372.5     89.9      html=s.get("https://en.wikipedia.org/").text
         8        50      5306958 106139.2     10.0      sum([pow(ord(x),3.1) for x in list(html)])
    
     

    Запрос страницы почти всегда медленнее, чем любой расчет, основанный на информации на странице.

  • 0

    Использование cProfile (Preferred Profiler)

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

    Он разбивает весь ваш скрипт и для каждого метода в вашем скрипте говорит вам:

    • ncalls : количество раз , когда метод был вызван
    • tottime : Общее время , проведенное в данной функции ( за исключением времени , сделанное в вызовах подфункций)
    • percall : Время , затраченное на вызов. Или частное от общего времени, деленное на ncalls
    • cumtime : Совокупное время , проведенное в этом и всех подфункциях (от вызова до выхода). Эта цифра точна даже для рекурсивных функций.
    • percall : это фактор cumtime делится на примитивных вызовов
    • filename:lineno(function) : предоставляет соответствующие данные каждой функции

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

     $ python -m cProfile main.py 
    
     

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

     $ python -m cProfile -s time main.py  

Синтаксис

Параметры

Примечания