Почему я не должен использовать PyPy поверх CPython, если PyPy работает в 6,3 раза быстрее?

686

Я много слышал о проекте PyPy . Они утверждают, что это в 6,3 раза быстрее, чем интерпретатор CPython на их сайте .

Всякий раз, когда мы говорим о динамических языках, таких как Python, скорость является одной из главных проблем. Чтобы решить эту проблему, говорят, что PyPy работает в 6,3 раза быстрее.

Вторая проблема - это параллелизм, печально известный Global Lock Interpreter Lock (GIL). Для этого PyPy говорит, что может дать Python без GIL .

Если PyPy может решить эти серьезные проблемы, каковы его слабые стороны, которые мешают более широкому принятию? То есть, что мешает кому-то, как я, типичному разработчику Python, перейти на PyPy прямо сейчас ?

чантель
источник
30
Очищенные комментарии, потому что большинство из них были вещами, которые либо должны быть конкретизированы в ответах (а в некоторых случаях таковыми являются), либо не должны быть сказаны вообще. Также отредактировано для решения пары проблем, поднятых в отношении субъективности этого вопроса. Пожалуйста, попробуйте ответить, используя факты, и, если возможно, подкрепите утверждения источниками!
Shog9
3
Я много использовал Pypy. Это имеет тенденцию работать очень хорошо. Однако, хотя Pypy немного быстрее для многих нагрузок на процессор, он на самом деле медленнее для нагрузок ввода-вывода, которые я выбрасывал. Например, я написал программу резервного копирования с дедупликацией, которая называется backshift. Для начальной резервной копии, которая выполняет много операций с файлами, pypy отлично подходит. Но для последующих резервных копий, которые в основном просто обновляют временные метки, CPython работает быстрее.
Дстромберг

Ответы:

657

ПРИМЕЧАНИЕ: PyPy более зрелый и лучше поддерживается, чем в 2013 году, когда был задан этот вопрос. Избегайте выводов из устаревшей информации.


  1. PyPy, как быстро заметили другие, имеет слабую поддержку расширений Си . Он имеет поддержку, но, как правило, со скоростью, меньшей скорости Python, и в лучшем случае сомнительна. Следовательно, многие модули просто требуют CPython. PyPy не поддерживает numpy PyPy теперь поддерживает numpy . Некоторые расширения по-прежнему не поддерживаются (Pandas, SciPy и т. Д.), Прежде чем вносить изменения, посмотрите список поддерживаемых пакетов .
  2. Поддержка Python 3 на данный момент является экспериментальной. только что достиг стабильного! По состоянию на 20 июня 2014 года, PyPy3 2.3.1 - Fulcrum вышла !
  3. Иногда PyPy на самом деле не быстрее для «скриптов», для которых многие используют Python. Это краткосрочные программы, которые делают что-то простое и маленькое. Поскольку PyPy является JIT-компилятором, его основные преимущества заключаются в длительном времени выполнения и простых типах (таких как числа). Честно говоря, скорость до JIT в PyPy довольно плохая по сравнению с CPython.
  4. Инерция . Переход на PyPy часто требует переоборудования, что для некоторых людей и организаций просто слишком много работы.

Это основные причины, которые влияют на меня, я бы сказал.

Veedrac
источник
14
Приятно, что вы упомянули переоснащение. Например, у моего веб-хостинга есть выбор между Python 2.4 и 2.5; а «крупный производитель развлекательного программного обеспечения», который находится рядом со мной, использует версию 2.6, и в ближайшее время не планирует обновляться. Иногда это может быть серьезным, дорогостоящим усилием даже для определения стоимости конверсии.
Майк Хауски
19
PyPy «работает так же быстро, как C» больше относится к универсальному C, чем к высокооптимизированным многопоточным библиотекам C с поддержкой кэширования, используемым для чисел. Для чисел Python просто используется для перемещения по указателям на большие массивы. Так что PyPy «так быстро, как C» означает «ваши указатели + метаданные перемещаются так же быстро, как C». Не так уж и важно. Тогда зачем вообще работать с Python? Посмотрите на подписи функций в cblas и lapacke.
cjordan1
12
@ cjordan1: я не понимаю, что вы говорите. NumPy конструкции высокого уровня чрезвычайно выразительны ( np.sum(M[1:2*n**2:2, :2*n**2] * M[:2*n**2:2, :2*n**2].conjugate(), axis=1)?) В Python, и это делает Python очень подходящим для научного сообщества. Кроме того, выполнение неинтенсивных частей в Python и выделение C для меньших интенсивных циклов является обычной и полезной стратегией.
Veedrac
26
@Veedrac Вот что я имел в виду. Как и в «Go, посмотрите на сигнатуры функций в cblas и lapacke», потому что они настолько длинные и сложные в использовании, что вы сразу поймете, почему мы используем Python для перемещения по указателям и метаданным.
cjordan1
5
@ tommy.carstensen Это не очень хорошее место для углубленного изучения, но я попробую. 1. Когда я написал это, это было намного более верно, чем сейчас. 2. «Скрипты» часто бывают тяжелыми. Ввод-вывод PyPy по-прежнему часто медленнее, чем в CPython - раньше он был значительно медленнее. 3. Раньше PyPy обрабатывал строки медленнее, чем CPython - теперь он часто лучше и редко хуже. 4. Многие «скрипты» - просто клеевой код - в этом случае ускорение интерпретатора не улучшит общее время выполнения. 5. Время разогрева PyPy было больше - короткие скрипты редко создавали много горячего кода.
Veedrac
104

Этот сайт не утверждает, что PyPy работает в 6,3 раза быстрее, чем CPython. Цитировать:

Среднее геометрическое для всех тестов в 0,16 или 6,3 раза быстрее, чем CPython

Это заявление очень отличается от общего заявления, которое вы сделали, и когда вы поймете разницу, вы поймете, по крайней мере, одну причину, по которой вы не можете просто сказать «использовать PyPy». Может показаться, что я придирчив, но важно понять, почему эти два утверждения совершенно разные.

Чтобы сломать это:

  • Заявление, которое они делают, относится только к тем эталонам, которые они использовали. Это абсолютно ничего не говорит о вашей программе (если ваша программа не совпадает с одним из их тестов).

  • Утверждение о среднем по группе тестов. Нет никаких гарантий, что запуск PyPy даст улучшение в 6,3 раза даже для протестированных программ.

  • Там нет никаких претензий , что PyPy даже запустить все программы , которые CPython работает вообще , не говоря уже быстрее.

spookylukey
источник
15
Конечно, нет никаких претензий, что PyPy будет выполнять весь код Python быстрее. Но если вы возьмете все чистые приложения Python, я могу поспорить, что значительное большинство из них будет работать намного быстрее (> 3 раза) на PyPy, чем на CPython.
Роберт Заремба
18
Ни один из ваших первых двух пунктов не имеет смысла. Как вы можете сказать, что тесты говорят "абсолютно ничего о вашей программе". Совершенно очевидно, что тесты не являются идеальным индикатором для всех реальных приложений, но они определенно могут быть полезны в качестве индикатора. Также я не понимаю, что вы вводите в заблуждение о том, что они сообщают о среднем по группе тестов. Они ясно заявляют, что это в среднем. Если программист не понимает, что такое среднее значение, тогда у него гораздо более серьезные проблемы, чем производительность языка.
Шон Джеффри Пиц
6
@SeanGeoffreyPietz - я не утверждал, что сайт PyPy каким-либо образом вводил в заблуждение - они точно представили свои результаты. Но первоначальный вопрос неверно процитировал их и продемонстрировал, что автор не понимает важности слова «средний». Многие из отдельных тестов не в 6,3 раза быстрее. А если вы используете среднее значение другого типа, вы получите другое значение, поэтому «6,3 х быстрее» не является адекватной сводкой «геометрическое среднее 6,3 х быстрее». «Группа A в Z раз быстрее, чем группа B» слишком расплывчата, чтобы иметь смысл.
spookylukey
6
-1: @spookylukey Похоже, вы полагаете, что набор тестов необъективен без предоставления доказательств в поддержку заявления. Критика всегда должна быть подкреплена доказательствами!
Евгений Сергеев
5
@EvgeniSergeev - нет, я намекаю на то, что все тесты смещены! Не обязательно сознательно, конечно. Пространство возможных полезных программ бесконечно и невероятно разнообразно, и набор тестов только измеряет производительность на этих тестах. На вопрос "насколько быстрее PyPy, чем CPython?" это все равно что спросить «насколько быстрее, если Фред, чем Джо?», это то, что ОП хочет знать.
Spookylukey
74

Поскольку pypy не совместим на 100%, для его компиляции требуется 8 ГБ ОЗУ, это движущаяся цель, и она очень экспериментальная, где cpython стабилен, цель по умолчанию для сборщиков модулей в течение 2 десятилетий (включая расширения c, которые не работают на pypy ) и уже широко развернут.

Pypy, вероятно, никогда не будет эталонной реализацией, но это хороший инструмент для использования.

Tritium21
источник
2
Согласно pypy.org/download.html , PyPy требуется 4 ГБ ОЗУ для компиляции (в 64-разрядной системе), а не 8. И на этой странице есть возможность сделать это под 3 ГБ, если это необходимо.
вязать
4
@ knite 1: это новое с 2015 года, документация исторически читала 8 ГБ. 2: на практике в 2015 году вам все равно нужно как минимум 8, причем 6-7 бесплатно.
Тритий21
4
Требования к памяти для компиляции не так актуальны, если вы используете сборку или дистрибутив . Что касается «движущейся цели, и очень экспериментальной», можете ли вы привести пару примеров того, что ломается? Опять же, если люди используют релизные сборки, а не ночные сборки или исходные тексты, разве они не имеют разумного ожидания функциональности?
smci
@smci Это древний вопрос, основанный на древних данных, с древними ответами. Считайте этот вопрос и каждый ответ историческим для состояния pypy 4 года назад.
Tritium21
1
@ Tritium21: меня интересует только текущий ответ. Что это? Вы можете отредактировать свой ответ, сказав: «По состоянию на 2013 год сравнение pypy с версией 2.x Python было ...» Кроме того, если утверждение «6.3x геометрическое среднее» в вопросе устарело ( как от 4/2017 они требуют 7.5x, но даже тогда зависит от тестов ... ), тогда это тоже требует редактирования (номера версий, последние данные и т. д.) Я думаю, что набор тестов не очень актуален, вряд ли кто-то будет запускать raytracing на языке сценариев на процессоре в эти дни. Я нашел pybenchmarks.org
smci
37

На второй вопрос легче ответить: вы в основном можете использовать PyPy в качестве замены, если весь ваш код - чистый Python. Однако многие широко используемые библиотеки (включая некоторые стандартные библиотеки) написаны на C и скомпилированы как расширения Python. Некоторые из них можно настроить для работы с PyPy, некоторые - нет. PyPy предоставляет тот же «обращенный вперед» инструмент, что и Python, т. Е. Python, но его внутренности разные, поэтому инструменты, взаимодействующие с этими внутренностями, работать не будут.

Что касается первого вопроса, я предполагаю, что это своего рода Catch-22 с первым: PyPy быстро развивается, пытаясь повысить скорость и улучшить совместимость с другим кодом. Это сделало его более экспериментальным, чем официальным.

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

BrenBarn
источник
17
Я не думаю, что C - это язык, который появится где угодно в ближайшее время (я хотел бы сказать, что он не исчезнет в нашей жизни). пока не будет другого языка, который будет работать где-либо, у нас будет C. (заметьте, JVM написана на C. Даже Java, языку, который "везде работает", нужен C для его универсальности.) В остальном я согласен с этим постом в большинстве из его точек.
Тритий21
7
@ Tritium21: Да, я просто редактирую там. Я в порядке с существующим C, но я думаю, что зависимость Python от C чрезвычайно пагубна, и PyPy является отличным примером того, почему: теперь у нас есть шанс получить более быстрый Python, но мы потрясены годами, полагаясь на C Питону было бы намного лучше встать на ноги. Это даже нормально, если сам Python написан на C, но проблема заключается в существовании механизма расширения, который поощряет людей расширять Python способами, зависящими от C.
BrenBarn
4
Двусторонний меч - часть того, что сделало Python столь популярным, - это его способность расширять другие приложения и расширяться другими приложениями. Если вы уберете это, я не думаю, что мы будем говорить о питоне.
Тритий21
10
@BrenBarn Глупо утверждать, что зависимость Python от C пагубна. Без C-API Python большинство действительно мощных библиотек и отличное взаимодействие, которое Python приобрел в первые годы (в конце 90-х), включая всю числовую / научную экосистему и интерфейсы GUI, были бы невозможны. Посмотрите вокруг, чтобы получить представление о целой вселенной использования Python, прежде чем делать такие общие заявления.
Питер Ван
4
@PeterWang Все эти библиотеки могут быть написаны на Python, однако они не будут такими быстрыми, как сейчас. Что говорит BrenBarn, так это то, что теперь у нас есть шанс сделать python достаточно быстрым, чтобы эти библиотеки могли быть написаны на python, но мы отказываемся использовать этот шанс, потому что использование этого означает потерю возможности использовать библиотеки C. Я полагаю, что это то, что он имел в виду под вредом, не то, что существование библиотек C - это плохо, а единственный способ создать быстрые библиотеки - это использование C.
vikki
14

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

Разработчики BDFL и CPython - удивительно умная группа людей, которым удалось помочь CPython отлично работать в таком сценарии. Вот бесстыдный плагин для блога: http://www.hydrogen18.com/blog/unpickling-buffers.html . Я использую Stackless, который является производным от CPython и сохраняет полный интерфейс модуля C. Я не нашел никакого преимущества в использовании PyPy в этом случае.

Эрик Урбан
источник
1
В PyPy есть много тщательно запущенных тестов производительности (в отличие от CPython, к сожалению, на данный момент у него нет набора тестов, ориентированных на пользователя). Конечно, для сетевого трафика PyPy не может сделать что-либо быстрее.
Джулиан
1
Джулиан, стоит отметить, что пользователи PyPy уже много лет уделяют много внимания улучшению времени выполнения этого конкретного набора тестов. В какой-то степени кажется, что они «подгоняют» свои оптимизации под этот набор тестов, и, по моему опыту, помимо чисто численных вычислений (которые в любом случае лучше в Fortran или C99), я никогда не получал PyPy более чем в 2 раза быстрее, чем CPython.
Алекс Рубинштейн
9
@AlexRubinsteyn Но мнение тех, кто работает над PyPy, обычно сводится к тому, что если вы обнаружите, что PyPy работает медленнее, чем CPython, и вы можете превратить его в приемлемый тест, он имеет хорошие шансы быть добавленным в пакет.
gsnedders
1
Я проверил твой блог. В ваших результатах пара простых python (pickle, StringIO) показывает, что pypy в ~ 6,8 раза быстрее, чем cpython. Я думаю, что это полезный результат. В своем заключении вы указываете (правильно), что pypy-код (который является простым python!) Медленнее, чем C-код (cPickle, cStringIO), а не cpython-код.
Калеб Хаттинг
1
@gsnedders я предложил тест , основанный на rinohtype в нескольких случаях . Они еще не добавили его в люкс.
Брехт Мачиэльс
12

В: Если PyPy может решить эти сложные задачи (скорость, потребление памяти, параллелизм) по сравнению с CPython, каковы его слабые стороны, мешающие более широкому внедрению?

A: Во-первых, мало доказательств того, что команда PyPy может решить проблему скорости в целом . Многолетние свидетельства показывают, что PyPy запускает некоторые коды Python медленнее, чем CPython, и этот недостаток, похоже, очень глубоко укоренен в PyPy.

Во-вторых, текущая версия PyPy потребляет намного больше памяти, чем CPython в довольно большом количестве случаев. Так что PyPy еще не решил проблему потребления памяти.

Если PyPy решает упомянутые большие проблемы и в целом будет быстрее, меньше память голодная, и более дружественной к параллельности , чем CPython является открытым вопросом , который не может быть решен в краткосрочной перспективе. Некоторые люди держат пари, что PyPy никогда не сможет предложить общее решение, позволяющее ему доминировать над CPython 2.7 и 3.3 во всех случаях.

Если PyPy окажется лучше, чем CPython в целом, что сомнительно, то основным недостатком, влияющим на его более широкое применение, будет его совместимость с CPython. Также существуют проблемы, такие как тот факт, что CPython работает на более широком диапазоне процессоров и операционных систем, но эти проблемы гораздо менее важны по сравнению с целями PyPy по производительности и совместимости с CPython.


В: Почему я не могу сделать замену CPython на PyPy сейчас?

A: PyPy не на 100% совместим с CPython, потому что он не имитирует CPython. Некоторые программы могут по-прежнему зависеть от уникальных возможностей CPython, которые отсутствуют в PyPy, таких как привязки C, реализации C объектов и методов Python или инкрементный характер сборщика мусора CPython.


источник
В этом ответе не приводятся какие-либо критерии или ссылки.
qwr
7

CPython имеет подсчет ссылок и сборщик мусора, PyPy имеет только сборку мусора.

Таким образом, объекты, как правило, удаляются раньше и __del__вызываются более предсказуемым способом в CPython. Некоторые программы полагаются на такое поведение, поэтому они не готовы к переходу на PyPy.

Некоторые другие программы работают с обоими, но используют меньше памяти с CPython, потому что неиспользуемые объекты освобождаются ранее. (У меня нет никаких измерений, чтобы указать, насколько это важно и какие другие детали реализации влияют на использование памяти.)

PTS
источник
17
Следует подчеркнуть, что полагаться на то, __del__что вас вызывают рано или вообще неправильно, даже в CPython. Как вы говорите, это обычно работает, и некоторые люди считают, что это гарантировано. Если что-либо, ссылающееся на объект, попадает в эталонный цикл (что довольно просто - знаете ли вы, что проверка текущего исключения определенным не надуманным способом создает эталонный цикл?), Завершение откладывается на неопределенное время до следующего цикла GC (что может быть никогда ). Если объект сам является частью эталонного цикла, __del__не будет вызываться вообще (до Python 3.4).
3
Издержки на объект выше в CPython, что очень важно, когда вы начинаете создавать множество объектов. Я считаю, что PyPy делает эквивалент слотов по умолчанию, с одной стороны.
4

Для многих проектов разница между питонами с точки зрения скорости составляет 0%. Это те, в которых доминирует время разработки и где все питоны имеют одинаковое количество библиотечной поддержки.

Стефан Эггермонт
источник
1
Если ваш проект настолько прост, то, очевидно, это не имеет значения, но то же самое можно сказать и о любой реализации любого языка: если все, что вы делаете, это объединяет функции других библиотек с помощью относительно производительных ABI, то все это не имеет значения.
1
Это не имеет ничего общего с простым. Во время разработки важна петля обратной связи. Иногда гораздо важнее времени выполнения.
Стефан Эггермонт
1
Ну, вы говорите очень расплывчато (время разработки без ссылки на то, что разрабатывается, каковы ограничения и т. Д .; цикл обратной связи без ссылки на то, кому что передается и т. Д.), Поэтому я собираюсь прекратить разговор, а не обмениваться загадочными ссылками.
Здесь нет ничего смутного. Взгляните на петлю OODA или PDCA.
Стефан Эггермонт
3
@user Что ж, любой проект, запускаемый один раз, для написания которого требуется месяц, а для запуска - минута, будет иметь общее увеличение скорости использования PyPy на 0,0% (1 месяц + 1 минута против 1 месяца), даже если PyPy был в тысячу раз быстрее. Стефан не утверждал, что все проекты будут иметь ускорение на 0%.
Gmatht
4

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

Ишен Чен
источник
16
«Батарея в комплекте» означает большую стандартную библиотеку ,
AFAIK
4

Я нашел примеры, где PyPy медленнее, чем Python. Но: только на Windows.

C:\Users\User>python -m timeit -n10 -s"from sympy import isprime" "isprime(2**521-1);isprime(2**1279-1)"
10 loops, best of 3: 294 msec per loop

C:\Users\User>pypy -m timeit -n10 -s"from sympy import isprime" "isprime(2**521-1);isprime(2**1279-1)"
10 loops, best of 3: 1.33 sec per loop

Итак, если вы думаете о PyPy, забудьте о Windows. В Linux вы можете добиться потрясающего ускорения. Пример (перечислите все простые числа от 1 до 1 000 000):

from sympy import sieve
primes = list(sieve.primerange(1, 10**6))

Это работает в 10 (!) Раз быстрее на PyPy, чем на Python. Но не на окнах. Там это только в 3 раза быстрее.

lifolofi
источник
Интересно! Еще несколько сравнений и цифр было бы здорово.
ben26941
1

PyPy уже некоторое время поддерживает Python 3, но, согласно сообщению Энтони Шоу от 2 апреля 2018 года в HackerNoon, PyPy3 все еще в несколько раз медленнее PyPy (Python 2).

Для многих научных вычислений, в частности, для матричных вычислений, лучше выбрать numpy (см. FAQ: стоит ли устанавливать numpy или numpypy? ).

Pypy не поддерживает gmpy2. Вместо этого вы можете использовать gmpy_cffi, хотя я не проверял его скорость, и у проекта был один выпуск в 2014 году.

Что касается задач Project Euler, я часто использую PyPy, а для простых численных расчетов часто from __future__ import divisionдостаточно для моих целей, но поддержка Python 3 все еще работает с 2018 года, и ваша лучшая ставка на 64-битный Linux. Windows PyPy3.5 v6.0, последняя по состоянию на декабрь 2018 года, находится в стадии бета-тестирования.

qwr
источник
0

Поддерживаемые версии Python

Чтобы процитировать дзен Python :

Читаемость имеет значение.

Например, Python 3.7 представил классы данных, а Python 3.8 представил fstring = .

В Python 3.7 и Python 3.8 могут быть другие функции, которые более важны для вас. Дело в том, что PyPy на данный момент не поддерживает Python 3.7 или Python 3.8.

Мартин Тома
источник