Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Что внутри у Питона: как работает интерпретатор

Что внутри у Питона: как работает интерпретатор

Злата Обуховская (Nvidia) @ Moscow Python Meetup 60

"Это первая из трёх лекций в цикле «Внутренности Питона». Мы разберёмся, как устроен Питон, посмотрим на этапы работы интерпретатора, построение деревьев разбора и генерацию байткода, а также выясним, какое пространство для оптимизаций нам это дает.

Если хотите больше знать про язык, на котором пишете, то приходите. Если уже все знаете, всё равно приходите".

Видео: http://www.moscowpython.ru/meetup/60/inside-python1/

Moscow Python Meetup

September 21, 2018
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. Зачем понимать, как работает питон? • повседневные прикладные задачи зачастую

    не повышают уровень инженерных навыков: ◦ проектирование архитектуры ◦ выбор подходящих для задачи технологий ◦ решение задачи оптимальным по трудозатратам способом • хорошие инженерные навыки помогают выполнять работу качественнее и быстрее • понимание внутренностей питона — один из способов повысить свой уровень
  2. Инициализация 1. pymain_main — точка входа 2. _Py_InitializeCore инициализует: •

    interpreter state • thread state • GIL • подгружает sys • подгружает builtins 3. PyRun_FileExFlags выделяет память, компилирует и интерпретирует
  3. Разбор кода PyParser_ParseFileObject: • инициализует токенайзер • разбивает файл на

    токены • использует LL-грамматику, определенную в Parser/Python.asdl • строит дерево разбора (parse tree)
  4. Дерево разбора • это список всех цепочек вывода для распаршенных

    токенов • для работы с деревьями вывода есть модуль parser • идентификаторы токенов можно найти в модулях symbol и token
  5. Abstract Syntax Tree • строится в PyAST_FromNodeObject • представляет программу

    в независимом от синтаксиса виде • может использоваться для оптимизаций программы • для работы с синтаксическими деревьями есть модуль ast
  6. Control Flow Graph и генерация байткода Генерация происходит в PyAST_CompileObject:

    • код разделяется на блоки • определяются области видимости переменных (global, local, builtins) • строится таблица символов • строится CFG • обходится граф • для каждого узла CFG генерится байткод и производятся оптимизации
  7. Интерпретация байткода Code object попадает в _PyEval_EvalCodeWithName: • инициализуется фрейм

    для выполнения кода • инициализует параметры вызова функции, переменные замыканий • вызывает _PyEval_EvalFrameDefault • попадает в цикл с огромным свитчем
  8. Генерация байткода: peephole optimizer имплементирован в Python/peephole.c • удаляет ненужные

    инструкции • оптимизирует jump-инструкции • арифметические оптимизации
  9. AST оптимизации в CPython можно сделать: • вычисление констант •

    copy propagation • dead code elimination • разворачивание циклов • builtins в константы нужны проверки изменения переменных
  10. Откуда так много питонов? • CPython • Stackless (свои микротреды)

    • Unladen swallow (все на llvm) • PyPy (RPython) • IronPython (генерят байткод для Mono) • Numba (подмножество питона, llvm, есть JIT) ТЫСЯЧИ ИХ!
  11. Выводы • CPython позволяет добиться тотальной мутабельности • Скорость выполнения

    при этом теряется • Оптимизации возможны за счет переписывания виртуальной машины • Можно оптимизировать процесс исполнения инструкций в vm • А можно вводить оптимизации из теории компиляторов