Specialist
Specialist использует высокоточную информацию о местоположении (fine-grained location), чтобы наглядно показать пользователю, где и как новый адаптивный интерпретирующий транслятор (specializing adaptive interpreter) CPython 3.11 оптимизирует ваш код. Подробности об инструменте — к старту курса по Fullstack-разработке на Python.
Установка
Specialist поддерживает CPython 3.11+ на всех платформах.
Для установки просто выполните:
$ pip install specialist
Принцип работы
Исполняя ваш код, CPython 3.11 выявляет самые «нагруженные» (hot) фрагменты кода, которые исполняются так часто, что за их счёт можно оптимизировать время исполнения кода. Он «ускоряет» эти места, которые specialist
размечает цветами.
Более тёмными и насыщенными цветами отмечается код, где «ускорить» можно много инструкций (то есть потенциал оптимизации велик). Места, где таких возможностей меньше, отмечены более светлыми и менее яркими цветами.
Как правило, «ускорение» происходит в три этапа:
-
Замена отдельных инструкций байт-кода на «адаптивные» формы. На самом деле они работают немного медленнее, чем обычные инструкции, поскольку периодически пытаются «оптимизироваться». Если они не могут сделать это, они остаются в адаптивной форме.
specialist
отмечает адаптивные инструкции красным цветом.
-
В некоторых случаях адаптивные инструкции преобразуются в гораздо более быстрые оптимизированные (specialized) инструкции. Примерами оптимизации являются доступ к атрибутам одного объекта или типа, вызовы некоторых «чисто пайтоновских» функций или сложение целых чисел.
specialist
использует зелёный цвет для обозначения оптимизированных инструкций.
-
Если через какое-то время оптимизация становится неэффективной (например, если выражение, которое ранее складывало два целых числа, вместо этого начинает объединять две строки), оптимизированную инструкцию можно преобразовать обратно в адаптивную. После этого цикл повторяется.
Specialist создан, чтобы дать представление о данном процессе как отладчикам самого CPython, так и пользователям, которые стремятся оптимизировать свой код.
Руководство
Пусть файл с исходным кодом conversions.py
преобразует градусы по Фаренгейту в градусы по Цельсию и обратно:
import math
def f_to_c(f: float) -> float:
"""Convert Fahrenheit to Celsius."""
x = f - 32
return x * 5 / 9
def c_to_f(c: float) -> float:
"""Convert Celsius to Fahrenheit."""
x = c * 9 / 5
return x + 32
TEST_VALUES = [-459.67, -273.15, 0.0, 32.0, 42.0, 273.15, 100.0, 212.0, 373.15]
def test_conversions() -> None:
for t in TEST_VALUES:
assert_round_trip(t)
def assert_round_trip(t: float) -> None:
# Round-trip Fahrenheit through Celsius:
assert math.isclose(t, f_to_c(c_to_f(t))), f"{t} F -> C -> F failed!"
# Round-trip Celsius through Fahrenheit:
assert math.isclose(t, c_to_f(f_to_c(t))), f"{t} C -> F -> C failed!"
if __name__ == "__main__":
test_conversions()
Запустить этот файл можно в CPython 3.11 из командной строки при помощи specialist
:
$ specialist conversions.py
По завершении запуска скрипта specialist
откроет браузер и отобразит размеченный исходный код программы:
Зелёным отмечены успешно оптимизированные фрагменты кода. Красным показаны фрагменты, которые оптимизировать не удалось (в виде «адаптивных» инструкций). Частично оптимизированные фрагменты показаны цветами из градиента «зелёный-жёлтый-оранжевый-красный, в зависимости от соотношения успехов и неудач оптимизации. Области кода, не затронутые попытками оптимизации, остались белыми.
Посмотрим на f_to_c
и c_to_f
. Здесь CPython не оптимизировал сложение с числом 32
и его вычитание. Сейчас он не поддерживает оптимизации бинарных операторов со смешанными значениями float
и int
. А эта часть кода посвящена именно этому.
Однако оптимизировать в нём сложение и вычитание двух значений float
можно! Замена результата 32
на 32.0
сделает оптимизацию успешной (что подтверждено при повторном вызове specialist
):
Подобное происходит и с умножением float
на int
. Можно продолжить преобразование постоянных значений во float
:
Но есть способ лучше! Обратите внимание, что CPython вовсе не пытается оптимизировать деление (на иллюстрации оно осталось белым). Мы можем использовать оптимизацию CPython по складыванию констант, слегка изменив порядок операций, что позволит вычислить масштабные коэффициенты (5 / 9
и 9 / 5
) на этапе компиляции. Когда мы это сделаем, CPython реализует наши конвертеры полностью с и помощью штатных операций с плавающей точкой:
Пара слов об оставшейся части кода:
-
Фрагмент, отвечающий за глобальный поиск
TEST_VALUES
, стал красным из-за того, что оптимизация подобных операций сейчас не поддерживается. Хотя раньше CPython мог оптимизироватьtest_conversions
и определял их как нагруженный код, после просмотраTEST_VALUES
(который происходит только один раз) этого не происходило. Неразумно тратить время на оптимизацию кода, который больше не будет выполняться!
-
По той же причине элементы
assert
в функцииassert_round_trip
выделены красным. Это «мёртвый» код: он не выполняется.
-
Вызов
math.is_close
отмечен оранжевым, ведь он реализован на C.
Расширения C нельзя «встроить» в код аналогично вызовам функций «чистого Python, напримерc_to_f
,f_to_c
,assert_round_trip
. По этой причине большая часть последовательности вызова того, что реализовано на C, не поддаётся оптимизации.
Режимы (modes)
Как и сам python
, specialist
можно использовать по-разному, например задавать путь к файлу:
$ specialist spam/eggs.py foo bar baz
название модуля:
$ specialist -m spam.eggs foo bar baz
или команду:
$ specialist -c 'import spam; spam.eggs()' foo bar baz
У него также есть опция поддержки выявления и анализа произвольных целевых файлов (target files) -t
/--targets
после исполнения скрипта. Это полезно, когда исполняемый скрипт отличается от кода, который хочется увидеть в specialist
:
$ specialist --targets spam/eggs.py -c 'import uses_eggs; uses_eggs.run()'
Несколько файлов можно представить через glob:
$ specialist --targets 'spam/**/*.py' -m pytest
Specialist может записывать сгенерированные HTML-файлы в файловую систему, не открывая их в браузере — просто укажите путь к выходному каталогу в опции -o
/-output
:
$ specialist --output ../report --targets 'spam/**/*.py' -m pytest
/home/brandtbucher/sketch/spam/__init__.py -> /home/brandtbucher/report/__init__.html
/home/brandtbucher/sketch/spam/_spammy.py -> /home/brandtbucher/report/_spammy.html
/home/brandtbucher/sketch/spam/eggs/__init__.py -> /home/brandtbucher/report/eggs/__init__.html
/home/brandtbucher/sketch/spam/eggs/_eggy.py -> /home/brandtbucher/report/eggs/_eggy.html
Опции
-b
/--blue
Оптимизированный код с этой опцией размечается синим, а не зелёным цветом. Некоторые люди лучше видят разницу цветов в градиенте «синий-фиолетовый-малиновый-красный», чем в стандартном градиенте «зелёный-жёлтый-оранжевый-красный».
-d
/--dark
Код будет отображаться светлым текстом на тёмном фоне. Некоторым пользователям так удобнее.
А мы научим вас аккуратно работать не только с кодом, но и с данными^
Новогодняя акция — скидки до 50% по промокоду HABR:
Data Science и Machine Learning
- Профессия Data Scientist
- Профессия Data Analyst
- Курс «Математика для Data Science»
- Курс «Математика и Machine Learning для Data Science»
- Курс по Data Engineering
- Курс «Machine Learning и Deep Learning»
- Курс по Machine Learning
Python, веб-разработка
- Профессия Fullstack-разработчик на Python
- Курс «Python для веб-разработки»
- Профессия Frontend-разработчик
- Профессия Веб-разработчик
Мобильная разработка
Java и C#
- Профессия Java-разработчик
- Профессия QA-инженер на JAVA
- Профессия C#-разработчик
- Профессия Разработчик игр на Unity
От основ — в глубину
А также
Комментарии (7)
dyadyaSerezha
10.12.2022 05:06например, если выражение, которое ранее складывало два целых числа, вместо этого начинает объединять две строки
Вот тут не понял. Как это?
Tzimie
10.12.2022 11:17Это же Питон
danSamara
11.12.2022 17:07Мне кажется, вы хотели иронично пошутить, но вышло не очень.
Во многих языках можно написать функцию, складывающую два типа/объекта, если для этого типа/объекта определенно сложение. В питоне и для строк и для чисел операция сложения определена.
Mihij
В первый раз о таком слышу. Тема оптимизации кода сейчас весьма актуальна. Спасибо. В ближайшее время испробую.