PyPy - Як це можливо перемогти CPython?


264

З блогу з відкритим кодом Google :

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

Як це можливо? Яка реалізація Python була використана для реалізації PyPy? CPython ? І які шанси на PyPyPy або PyPyPyPy побити їх рахунок?

(У відповідній записці ... чому б хтось спробував щось подібне?)


43
Нітпік: PyPy - це PyPyPy. Подумайте про префікс Py- * як оператор проекції.
u0b34a0f6ae

Гаразд. тому PyPy слід віддавати перевагу, ніж CPython? чи є якісь недоліки?
balki

10
PyPy чудово підходить для оптимізації часу виконання, але різні його внутрішні властивості роблять його несумісним з кількома популярними розширеннями C.
Cees Timmerman

4
Практично кожному не вистачає питання про те, як підвищення швидкості ТЕОРЕТИЧНО можливий. Але подумайте: Python може робити все, що завгодно, як і машина Тьюрінга. Це може зателефонувати gcc, зрештою. Таким чином, ви також можете написати якийсь код python, який працює на CPython, який інтерпретує якийсь інший код python, переводить його на C і виконує gcc, а потім виконує компільовану програму. І це може бути швидше, якщо код називається досить часто.
osa

Відповіді:


155

Q1. Як це можливо?

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

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

Як згадував Марсело, СТІ. Можливість на ходу підтвердити тип об'єкта може врятувати вам необхідність зробити кілька перенапряжень покажчиків, щоб нарешті дійти до методу, який ви хочете зателефонувати.

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?


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 пропуск), другий для комбінації: тому що Pypy JIT може "вбудовуватися через межі бібліотеки", приклад функції "printf" спеціалізується на тому, щоб буквально бути здатним випромінювати ціле число і виключати повторний malloc (наділення пам'яті накладними).
амкгрегор

291

"PyPy - це повторне втілення Python в Python" - це досить оманливий спосіб описати PyPy, IMHO, хоча технічно це правда.

Є дві основні частини 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. Тож рамки перекладу величезнізусилля, але це однаково добре застосовується до інтерпретатора PyPy python, проте вони змінюють свою реалізацію, дозволяючи набагато більше свободи в експерименті для підвищення продуктивності (не турбуючись про введення помилок 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 написаний на обмеженому Python. Наскільки я знаю, він не працює над інтерпретатором CPython. Обмежений Python - це підмножина мови Python. AFAIK, інтерпретатор PyPy компілюється до машинного коду, тому при його встановленні він не використовує інтерпретатора python під час виконання.

Здається, ваше запитання очікує, що інтерпретатор PyPy працює над CPython під час виконання коду. Редагувати: Так, щоб користуватися PyPy, ви спершу перекладаєте код PyPy python, або в C, і будуйте з gcc, в байт-код jvm або в .Net код CLI. Див. Початок роботи


8
PyPy працюватиме поверх CPython, але в цьому режимі він не забезпечує збільшення швидкості, яку можна побажати. :-) codepeak.net/pypy/dist/pypy/doc/…
Франк V
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.