Содержание страницы
profiling – профилировщики Python¶profiling – Python profilers
Добавлено в версии 3.15.
Исходный код: Lib/profiling/
Введение в профилирование¶Introduction to profiling
A profile is a set of statistics that describes how often and for how long various parts of a program execute. These statistics help identify performance bottlenecks and guide optimization efforts. Python provides two fundamentally different approaches to collecting this information: statistical sampling and deterministic tracing.
Пакет profiling объединяет встроенные инструменты профилирования Python в едином пространстве имён. Он содержит два подмодуля, каждый из которых реализует свой метод профилирования:
profiling.samplingСтатистический профилировщик, который периодически делает выборки стека вызовов. Можно запускать скрипты напрямую или подключаться к работающим процессам по PID. Предоставляет множество форматов вывода (flame graphs, heatmaps, Firefox Profiler), анализ GIL, отслеживание GC и несколько режимов профилирования (реальное время, процессор, GIL) практически без накладных расходов.
profiling.tracingДетерминированный профилировщик, который отслеживает каждый вызов функции, возврат и событие исключения. Предоставляет точное количество вызовов и точную информацию о времени, захватывая каждый вызов, включая очень быстрые функции.
Примечание
Модули профилировщика предназначены для получения профиля выполнения программы, а не для бенчмаркинга. Для бенчмаркинга используйте модуль timeit, который обеспечивает достаточно точные измерения времени. Это различие особенно важно при сравнении кода Python с кодом на C: детерминированные профилировщики добавляют накладные расходы для кода Python, но не для функций уровня C, что может исказить сравнение.
Выбор профилировщика¶Choosing a profiler
Для большинства задач анализа производительности используйте статистический профилировщик (profiling.sampling). Он имеет минимальные накладные расходы, работает как в разработке, так и в production, и предоставляет богатые возможности визуализации, включая флейм-графы, тепловые карты, анализ GIL и другое.
Используйте детерминированный профилировщик (profiling.tracing), когда вам нужны точные значения количества вызовов и нельзя пропустить ни одного вызова функции. Поскольку он инструментирует каждый вызов и возврат, он захватит даже очень быстрые функции, которые завершаются между интервалами выборки. Плата за это – более высокие накладные расходы.
В следующей таблице приведены ключевые различия:
Возможность |
Статистическая выборка
( |
Детерминированный
( |
|---|---|---|
Накладные расходы |
Практически отсутствуют |
Умеренные |
Точность |
Статистическая оценка |
Точное количество вызовов |
Форматы вывода |
pstats, флейм-граф, тепловая карта, gecko, свёрнутый |
pstats |
Режимы профилирования |
Реальное время, процессор, GIL |
Реальное время |
Специальные кадры |
GC, нативный (расширения C) |
Н/Д |
Подключение к PID |
Да |
Нет |
Когда использовать статистическую выборку¶When to use statistical sampling
Статистический профилировщик (profiling.sampling) рекомендуется для большинства задач анализа производительности. Используйте его так же, как profiling.tracing:
python -m profiling.sampling run script.py
Одна из главных сильных сторон профилировщика на основе выборки – разнообразие форматов вывода. Помимо традиционных таблиц pstats, он может создавать интерактивные флейм-графы, визуализирующие иерархии вызовов, построчные тепловые карты исходного кода, показывающие, где именно тратится время, и вывод для Firefox Profiler для анализа на временной шкале.
Профилировщик также позволяет заглянуть во внутреннее поведение интерпретатора Python, которое недоступно при детерминированном профилировании. Используйте --mode gil для выявления конкуренции за GIL в многопоточном коде, --mode cpu для измерения реального времени процессора без учёта ожидания ввода-вывода, или проверяйте кадры <GC>, чтобы понять накладные расходы на сборку мусора. Опция --native показывает время, затраченное в расширениях C, помогая отличить накладные расходы Python от производительности библиотек.
Для многопоточных приложений опция -a выполняет выборку всех потоков одновременно, показывая, как распределяется работа. А для отладки в production команда attach подключается к любому работающему процессу Python по PID без необходимости перезапуска или изменения кода.
Когда использовать детерминированную трассировку¶When to use deterministic tracing
Детерминированный профилировщик (profiling.tracing) инструментирует каждый вызов функции и возврат. Этот подход имеет более высокие накладные расходы, чем выборка, но гарантирует полное покрытие выполнения программы.
Основная причина выбрать детерминированную трассировку – необходимость точного подсчёта вызовов. Статистическое профилирование оценивает частоту на основе выборки, что может недооценивать короткоживущие функции, которые завершаются между выборками. Если требуется проверить, что оптимизация действительно уменьшила количество вызовов функций, или проследить полный граф вызовов, чтобы понять отношения вызывающих и вызываемых функций, детерминированная трассировка – правильный выбор.
Детерминированная трассировка также отлично подходит для захвата функций, выполняющихся за микросекунды. Такие функции могут появляться недостаточно часто в статистических выборках, но детерминированная трассировка записывает каждый вызов независимо от длительности.
Быстрый старт¶Quick start
Этот раздел содержит минимальные шаги, необходимые для начала профилирования. Полную документацию см. на страницах, посвящённых каждому профилировщику.
Статистическое профилирование¶Statistical profiling
Чтобы профилировать скрипт, используйте модуль profiling.sampling с командой run:
python -m profiling.sampling run script.py
python -m profiling.sampling run -m mypackage.module
Это запускает скрипт под профилировщиком и выводит сводку о том, где было потрачено время. Для интерактивного графа пламени:
python -m profiling.sampling run --flamegraph script.py
Чтобы профилировать уже запущенный процесс, используйте команду attach с идентификатором процесса:
python -m profiling.sampling attach 1234
Для настраиваемых параметров укажите интервал выборки (в микросекундах) и длительность (в секундах):
python -m profiling.sampling run -i 50 -d 30 script.py
Детерминированное профилирование¶Deterministic profiling
Чтобы профилировать скрипт из командной строки:
python -m profiling.tracing script.py
Чтобы профилировать фрагмент кода программно:
import profiling.tracing
profiling.tracing.run('my_function()')
Это выполняет заданный код под профилировщиком и выводит сводку, показывающую точное количество вызовов функций и время.
Понимание вывода профилировщика¶Understanding profile output
Оба профилировщика собирают статистику на уровне функций, хотя представляют её в разных форматах. Профилировщик на основе выборки предлагает несколько визуализаций (графы пламени, тепловые карты, Firefox Profiler, таблицы pstats), в то время как детерминированный профилировщик создаёт вывод, совместимый с pstats. Независимо от формата, основные концепции одинаковы.
Ключевые концепции профилирования:
- Прямое время (также называется собственным временем или tottime)
Время, потраченное на выполнение кода в самой функции, за исключением времени, затраченного в вызванных ею функциях. Высокое прямое время указывает на то, что функция содержит дорогостоящие операции.
- Совокупное время (также называется общим временем или cumtime)
Время, потраченное в функции и всех вызванных ею функциях. Это измеряет общую стоимость вызова функции, включая всё поддерево вызовов.
- Количество вызовов (также называется ncalls или выборки)
Сколько раз функция была вызвана (детерминированное) или попала в выборку (статистическое). При детерминированном профилировании это точное значение. При статистическом профилировании оно представляет количество раз, когда функция появилась в стековой выборке.
- Примитивные вызовы
Вызовы, которые не вызваны рекурсией. Когда функция рекурсивна, общее количество вызовов включает рекурсивные вызовы, но примитивные вызовы учитывают только первоначальный вход. Отображается как
total/primitive(например,3/1означает три общих вызова, один примитивный).- Отношения вызывающих и вызываемых функций
Какие функции вызывали данную функцию (вызывающие) и какие функции она вызывала (вызываемые). Графы пламени визуализируют это в виде вложенных прямоугольников; pstats может отобразить это с помощью методов
print_callers()иprint_callees().
Совместимость с предыдущими версиями¶Legacy compatibility
Для обратной совместимости модуль cProfile остаётся доступным как псевдоним для profiling.tracing. Существующий код, использующий import cProfile, будет продолжать работать без изменений во всех будущих версиях Python.
Устарело с версии 3.15: Чистый Python модуль profile устарел и будет удалён в Python 3.17. Вместо него используйте profiling.tracing (или его псевдоним cProfile). См. profile для руководства по миграции.
См. также
profiling.samplingСтатистический профилировщик на основе выборки с графами пламени, тепловыми картами и анализом GIL. Рекомендован для большинства пользователей.
profiling.tracingДетерминированный трассирующий профайлер для точного подсчёта вызовов.
pstatsАнализ статистики и форматирование данных профилирования.
timeitМодуль для измерения времени выполнения небольших фрагментов кода.
Подмодули