PyPy - Как это может победить CPython?

264

Из блога Google с открытым исходным кодом :

PyPy - это повторная реализация Python в Python, использующая передовые методы для достижения лучшей производительности, чем CPython. Много лет тяжелой работы наконец окупились. Наши результаты по скорости часто опережают CPython, начиная от чуть медленнее, до ускорений в 2 раза для реального кода приложения и до 10 раз в небольших тестах.

Как это возможно? Какая реализация Python использовалась для реализации PyPy? CPython ? И каковы шансы того, что PyPyPy или PyPyPyPy победят?

(Относительно примечания ... зачем кому-то пытаться что-то подобное?)

Агнель Курьян
источник
43
Nitpick: PyPy - это PyPyPy. Думайте о префиксе Py- * как о проекционном операторе.
u0b34a0f6ae
Хорошо. поэтому PyPy должен быть предпочтительнее, чем CPython? есть ли у него недостатки?
балки
10
PyPy отлично подходит для оптимизации во время выполнения, но его различные особенности делают его несовместимым с несколькими популярными расширениями Си.
Сис Тиммерман
4
Почти все упускают вопрос о том, как теоретически возможно увеличение скорости. Но подумайте об этом: Python может делать что угодно, как машина Тьюринга. Это может позвонить gcc, в конце концов. Таким образом, вы также можете написать некоторый код Python, который работает на CPython, который интерпретирует некоторый другой код Python, переводит его в C и выполняет gcc, а затем выполняет скомпилированную программу. И это может быть быстрее, если код вызывается достаточно часто.
Ос

Ответы:

155

Q1. Как это возможно?

Ручное управление памятью (что делает CPython со своим счетом) может быть медленнее, чем автоматическое управление в некоторых случаях.

Ограничения в реализации интерпретатора CPython исключают некоторые оптимизации, которые может выполнять PyPy (например, мелкозернистые блокировки).

Как отметил Марсело, JIT. Возможность на лету подтвердить тип объекта может избавить вас от необходимости многократного разыменования указателя, чтобы в итоге получить метод, который вы хотите вызвать.

Q2. Какая реализация Python использовалась для реализации PyPy?

Интерпретатор PyPy реализован в RPython, который является статически типизированным подмножеством Python (язык, а не интерпретатор CPython). - Подробнее см. Https://pypy.readthedocs.org/en/latest/architecture.html .

Q3. И каковы шансы того, что PyPyPy или PyPyPyPy победят?

Это будет зависеть от реализации этих гипотетических интерпретаторов. Если один из них, например, взял исходный код, выполнил какой-то анализ и преобразовал его непосредственно в узкий целевой код сборки после некоторого времени работы, я думаю, это будет гораздо быстрее, чем CPython.

Обновление: недавно, на тщательно созданном примере , PyPy превзошел аналогичную C-программу, скомпилированную gcc -O3. Это надуманный случай, но он демонстрирует некоторые идеи.

Q4. Зачем кому-то пытаться что-то подобное?

С официального сайта. https://pypy.readthedocs.org/en/latest/architecture.html#mission-statement

Мы стремимся предоставить:

  • общая структура перевода и поддержки для создания
    реализаций динамических языков, подчеркивая четкое
    разделение между спецификацией языка и
    аспектами реализации . Мы называем это RPython toolchain_.

  • совместимая, гибкая и быстрая реализация языка Python_, которая использует вышеупомянутую цепочку инструментов для включения новых расширенных функций высокого уровня без необходимости кодировать детали низкого уровня.

Разделяя проблемы таким образом, наша реализация Python - и других динамических языков - способна автоматически генерировать компилятор Just-in-Time для любого динамического языка. Он также допускает подход «смешай и сопоставляй» к решениям по реализации, включая многие, которые исторически находились вне контроля пользователя, такие как целевая платформа, модели памяти и потоков, стратегии сбора мусора и применяемые оптимизации, в том числе необходимость JIT в первую очередь.

Компилятор C gcc реализован на C, компилятор Haskell GHC написан на Haskell. У вас есть причина, по которой интерпретатор / компилятор Python не будет написан на Python?

Noufal Ibrahim
источник
82
В этом ответе полностью отсутствует основное объяснение того, как быстро PyPy; хотя в нем упоминается, что PyPy на самом деле не реализован в Python, но в RPython, он не указывает на то, что код RPython статически компилируется и оптимизируется для создания интерпретатора PyPy (он также является допустимым кодом Python, который может выполняться поверх CPython гораздо медленнее). В «нормальном Python» они реализовали «компилятор» RPython (каркас перевода, указанный в кавычках).
Бен
12
Это хоронит Леду. Большая часть производительности исходит от перевода на C (что делает интерпретатор не намного медленнее, чем CPython) и JIT, который делает горячие пути намного быстрее.
Тобу
4
«Обновление: недавно, на тщательно созданном примере, PyPy превзошел аналогичную программу на C, скомпилированную с gcc -O3». И если вы прочтете первый комментарий под этим постом, вы увидите, что автор этого поста не знает оптимизации во время ссылки. С включенной оптимизацией во время соединения код C работает быстрее.
Али
2
Ну, пост в блоге был в 2011 году, а этот ответ - в 2014 году. Также в комментарии упоминаются общие библиотеки. Я не знаю, сколько из этого (ответ и сообщение в блоге) является действительным. Все задействованные технологии сильно изменились за последние несколько лет.
Нуфал Ибрагим
1
На двух тщательно разработанных примерах Pypy быстрее, чем эквивалентный C, каждый из них быстрее в тесте по очень конкретному набору причин. Первое, потому что Pypy достаточно умен, чтобы понимать, что в подсчете с плотным циклом никогда не используется этот счет, поэтому он может быть полностью удален (проход JIT), второе для комбинации: потому что JIT Pypy может «встроиться через границы библиотеки», учитывая пример функции printf, специализирующейся на том, чтобы буквально иметь возможность выдавать только целое число, и устраняет повторяющиеся malloc (накладные расходы на выделение памяти).
amcgregor
291

«PyPy - это повторная реализация Python в Python» - это довольно обманчивый способ описать PyPy, ИМХО, хотя это технически верно.

Есть две основные части PyPy.

  1. Структура перевода
  2. Переводчик

Структура перевода - это компилятор. Он компилирует код RPython до C (или других целей), автоматически добавляя такие аспекты, как сборка мусора и JIT-компилятор. Он не может обрабатывать произвольный код Python, только RPython.

RPython - это подмножество нормального Python; Весь код RPython - это код Python, но не наоборот. Формального определения RPython не существует, потому что RPython - это просто «подмножество Python, которое можно перевести с помощью среды перевода PyPy». Но для перевода код RPython должен быть статически типизирован (типы выводятся, вы не объявляете их, но это по-прежнему строго один тип для каждой переменной), и вы не можете делать такие вещи, как объявление / изменение функций / занятия во время выполнения либо.

Таким образом, интерпретатор - это обычный интерпретатор Python, написанный на RPython.

Поскольку код RPython - это обычный код Python, вы можете запустить его на любом интерпретаторе Python. Но ни одно из заявлений PyPy о скорости не исходит из того, что он работает таким образом; это просто для быстрого цикла тестирования, потому что перевод переводчика занимает много времени.

С этим пониманием должно быть сразу очевидно, что спекуляции о PyPyPy или PyPyPyPy на самом деле не имеют никакого смысла. У вас есть переводчик, написанный на RPython. Вы переводите его в код C, который быстро выполняет Python. Там процесс останавливается; больше нет RPython, чтобы ускорить его обработку.

Так что «Как PyPy может быть быстрее, чем CPython» также становится довольно очевидным. PyPy имеет лучшую реализацию, включая JIT-компилятор (я думаю, что без JIT-компилятора, как правило, не так быстро, что означает, что PyPy быстрее только для программ, чувствительных к JIT-компиляции). CPython никогда не была разработана , чтобы быть в высшей степени оптимизации реализации языка Python (хотя они и пытаются сделать его высоко оптимизированную реализацию, если вы будете следовать разнице).


Действительно инновационный аспект проекта PyPy заключается в том, что они не пишут сложные схемы GC или JIT-компиляторы вручную. Они пишут интерпретатор относительно просто в RPython, и для всех RPython является более низким уровнем, чем Python, он все еще является объектно-ориентированным языком сборки мусора, гораздо более высоким уровнем, чем C. Затем инфраструктура перевода автоматически добавляет такие вещи, как GC и JIT. Таким образом, рамки перевода огромныусилия, но это в равной степени относится и к интерпретатору Python PyPy, однако они меняют свою реализацию, предоставляя гораздо большую свободу в экспериментах для повышения производительности (не беспокоясь о появлении ошибок GC или обновлении JIT-компилятора, чтобы справиться с изменениями). Это также означает, что когда они приступят к реализации интерпретатора Python3, он автоматически получит те же преимущества. И любые другие интерпретаторы, написанные с помощью платформы PyPy (которых на разных этапах полировки много). И все интерпретаторы, использующие платформу PyPy, автоматически поддерживают все платформы, поддерживаемые платформой.

Таким образом, истинное преимущество проекта PyPy состоит в том, чтобы отделить (насколько это возможно) все части реализации эффективного независимого от платформы интерпретатора для динамического языка. А затем придумайте одну хорошую реализацию их в одном месте, которую можно будет повторно использовать во многих переводчиках. Это не немедленная победа, как «моя Python-программа работает быстрее сейчас», но это большая перспектива на будущее.

И он может запустить вашу программу на Python быстрее (возможно).

Бен
источник
4
Я не мог проследить разницу :(
polvoazul
37
@polvoazul Разница между оптимизированной реализацией языка и оптимизирующей ? Что ж, когда я говорю, что CPython - это хорошо оптимизированная реализация, я имею в виду, что разработчики пытаются заставить внутренние алгоритмы самого интерпретатора и встроенные структуры данных работать эффективно. Оптимизации реализации, Ото, будет анализировать конечные пользователи код и попытаться выяснить способы , чтобы превратить его в более эффективно выполнять.
Бен
23

PyPy реализован на Python, но он реализует JIT-компилятор для генерации нативного кода на лету.

Причиной реализации PyPy поверх Python, вероятно, является то, что это просто очень производительный язык, тем более что JIT-компилятор делает производительность основного языка несколько нерелевантной.

Марсело Кантос
источник
Генерирует ли JIT код Python, работающий на том же уровне, что и PyPy, или генерирует реальный собственный код, работающий на уровне любой реализации Python, на которой работает PyPy?
Эдмунд
3
Настоящий нативный код (см. Здесь ); 32-битный код x86, если быть точным.
Марсело Кантос
11

PyPy написан на Restricted Python. Насколько я знаю, он не работает поверх интерпретатора CPython. Ограниченный Python является подмножеством языка Python. AFAIK, интерпретатор PyPy скомпилирован в машинный код, поэтому при установке он не использует интерпретатор Python во время выполнения.

Похоже, ваш вопрос предполагает, что интерпретатор PyPy выполняется поверх CPython при выполнении кода. Изменить: Да, чтобы использовать PyPy, вы сначала переводите код Python PyPy, либо в C, и собираете его с помощью gcc, в байтовый код jvm или в код .NET CLI. Смотрите Начало работы

оборота бобпаул
источник
8
PyPy будет работать поверх CPython, но в этом режиме он не обеспечивает желаемого прироста скорости. :-) codespeak.net/pypy/dist/pypy/doc/…
Фрэнк V