Pull to refresh

Профилирование python приложений

Reading time 2 min
Views 16K
Краткая заметка с линками и примерами о профайлинге:
  1. производительности: hotshot или python profile/cProfile + визуализатор логов kcachegrind (есть порт под windows, аналог WinCacheGrind)
  2. использование памяти: dowser с web-интерфейсом


производительность


  1. собираем статистику профайлером, варианты:

    • пример 1, с помощью быстрого hotshot (который может стать deprecated):
      import hotshot
      prof = hotshot.Profile("your_project.prof")
      prof.start()
        
      # your code goes here
           
      prof.stop()
      prof.close()

      конвертируем формат логов с помощью утилиты из пакета kcachegrind-converters:
      hotshot2calltree your_project.prof > your_project.out

    • пример 2, с помощью стандартного profile/cProfile:
      python -m cProfile -o your_project.pyprof your_project.py
      

      конвертируем формат логов с помощью pyprof2calltree:
      pyprof2calltree -i your_project.pyprof -o your_project.out

      (с опцией -k он сразу запустит kcachegrind и промежуточного файла создавать не нужно)


  2. открываем и изучаем лог в визуализаторе kcachegrind


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



память


К сожалению еще не знаю средств чтобы было так же просто и приятно. Рыться в дебагере не хотелось, остался недоволен Guppy — он силен, но сложен — так часто профилировать к счастью не приходится. Objgraph тоже не предоставляет возможности легкой навигации вне дебаг-оболочки.

Мой выбор сейчас, это dowser, приложение с интерфейсом на CherryPy. С ним все проще, хоть и не настолько гибко:

  1. создаем контроллер, по сути CherryPy 3 приложение:
    # memdebug.py
    
    import cherrypy
    import dowser
    
    def start(port):
        cherrypy.tree.mount(dowser.Root())
        cherrypy.config.update({
            'environment': 'embedded',
            'server.socket_port': port
        })
        cherrypy.engine.start() 

  2. подключаем к своему приложению:
    import memdebug
    memdebug.start(8080)
    
    # your code goes here

  3. идем в браузер и просматриваем статистику (игнорируем объекты CherryPy, других библиотек — ищем только наши)
     http://localhost:8080/




    Функционал аскетичен, немного придется покликать и разобраться, но его вполне хватает для поиска проблем. Нет необходимости изучать и запоминать API дебагера. Внимание, на некоторых операциях как «Show the entire tree», может затребовать неймоверное количество памяти для больших приложений.
  4. приложение само не закроется. После изучения прерываем Ctrl+Z и убиваем

О каких методах и средствах профилирования еще стоит узнать?
Tags:
Hubs:
+31
Comments 22
Comments Comments 22

Articles