Что такое py-spy, отличие от cProfile, установка и первое профилирование
Профилирование — это не оптимизация. Это понимание того, что на самом деле делает ваш код.
Представьте: у вас есть медленный API, который отвечает 5 секунд вместо 200 мс. Где проблема?
Без профилирования вы будете:
print(time.time()) в разные местаС профилированием вы:
| Характеристика | cProfile | py-spy |
|---|---|---|
| Тип | Детерминированный | Семплирующий |
| Замедление | 2-10× | <5% |
| Работа с продакшеном | ❌ Нельзя | ✅ Можно |
| Модификация кода | Требуется импорт | Не требуется |
| Нативные расширения | Не показывает | Показывает (с --native) |
| Multiprocessing | Сложно | Работает из коробки |
Детерминированный профилировщик (cProfile) отслеживает каждый вызов функции. Это даёт точные данные, но замедляет программу.
Семплирующий профилировщик (py-spy) периодически снимает «снимки» стека вызовов. Например, 100 раз в секунду. Если функция появилась в 50 снимках из 100, она занимала ~50% времени.
Почему это важно? py-spy можно запустить на работающем продакшен-сервере без остановки и без заметного влияния на пользователей.
py-spy — это один бинарный файл. Никаких зависимостей, никаких pip install.
brew install py-spyИли скачайте с GitHub Releases:
curl -L https://github.com/benfred/py-spy/releases/download/v0.4.0/py-spy-0.4.0-x86_64-apple-darwin.tar.gz | tar xz
mv py-spy /usr/local/bin/pip install py-spyИли скачайте бинарник:
curl -L https://github.com/benfred/py-spy/releases/download/v0.4.0/py-spy-0.4.0-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv py-spy /usr/local/bin/Скачайте .exe с GitHub Releases и поместите в PATH.
py-spy --version
# py-spy 0.4.0Создайте тестовый скрипт slow_script.py:
import time
import math
def slow_function():
"""Намеренно медленная функция"""
total = 0
for i in range(1_000_000):
total += math.sqrt(i)
return total
def fast_function():
"""Быстрая функция"""
return sum(range(100))
def main():
print("Начало работы...")
# Медленная часть
for _ in range(5):
slow_function()
# Быстрая часть
for _ in range(100):
fast_function()
print("Готово!")
if __name__ == "__main__":
main()Способ 1: Профилирование с запуска
py-spy record -o profile.svg -- python slow_script.pyЧто происходит:
python slow_script.pyprofile.svgСпособ 2: Профилирование работающего процесса
Запустите скрипт в одном терминале:
python slow_script.pyНайдите PID (в другом терминале):
ps aux | grep slow_script
# или
pgrep -f slow_script.pyЗапустите профилирование:
py-spy record -o profile.svg --pid <PID>Важно: На macOS и Linux может потребоваться
sudoдля профилирования работающего процесса:sudo py-spy record -o profile.svg --pid 12345
Откройте profile.svg в браузере. Вы увидите icicle graph (граф-сосульку):
┌─────────────────────────────────────────┐
│ slow_function (85%) │ ← Занимает 85% времени
├─────────────────────────────────────────┤
│ main (90%) fast_function (5%) │
└─────────────────────────────────────────┘
Как читать:
В нашем примере вы сразу увидите, что slow_function занимает почти всё время.
py-spy использует возможности операционной системы для чтения памяти другого процесса:
/proc/<PID>/mem и /proc/<PID>/regstask_for_pid и Mach APIReadProcessMemoryОн читает структуры данных интерпретатора Python (фреймы, кодовые объекты) напрямую из памяти. Программа продолжает выполняться — py-spy просто «подглядывает».
Безопасно ли это? Да. py-spy только читает память, не модифицирует её. Это как сделать фотографию — программа не знает, что её профилируют.
Точность: Семплирование даёт статистическую картину, а не точные числа. Для 99% случаев этого достаточно.
Короткие функции: Если функция выполняется быстрее интервала семплирования (10 мс по умолчанию), она может не попасть в профиль.
Требования к процессу:
ptrace_scope=0 (см. ниже)Если py-spy не подключается к процессу:
# Проверьте ptrace_scope
cat /proc/sys/kernel/yama/ptrace_scope
# Если не 0, временно отключите
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scopeИли используйте --non-blocking флаг.
Вы установили py-spy и запустили первое профилирование. В следующих темах:
slow_script.py из примера вышеpy-spy record -o profile.svg -- python slow_script.pyprofile.svg в браузереКлючевая идея: py-spy даёт вам данные, а не догадки. Одна команда — и вы видите, где программа на самом деле проводит время.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.