Чому я не повинен використовувати PyPy над CPython, якщо PyPy в 6,3 рази швидший?


685

Я багато чув про проект PyPy . Вони стверджують, що це в 6,3 рази швидше, ніж інтерпретатор CPython на їхньому сайті .

Щоразу, коли ми говоримо про динамічні мови, як-от Python, швидкість - це одна з головних проблем. Щоб вирішити це, вони кажуть, що PyPy у 6,3 рази швидший.

Друге питання - паралелізм, сумнозвісний замок глобальних перекладачів (GIL). З цього приводу PyPy каже, що він може давати Python без GIL .

Якщо PyPy може вирішити ці великі виклики, то які її слабкі сторони перешкоджають більш широкому впровадженню? Тобто, що заважає комусь, як я, типовому розробнику Python, перейти на PyPy зараз ?


30
Проціджені коментарі, оскільки більшість речей, на які слід або конкретизувати відповіді (а в деяких випадках є), або взагалі не слід говорити. Також відредаговано для вирішення декількох проблем, що виникають щодо суб'єктивності цього питання. Спробуйте відповісти, використовуючи факти, і, якщо можливо, резервні копії тверджень із джерелами!
Shog9

3
Я багато використовував Pypy. Це, як правило, працює дуже добре. Однак, хоча Pypy досить швидкий для багатьох завантажених процесором навантажень, він фактично повільніше для великої завантаженості вводу / виводу, яку я на нього кинув. Наприклад, я написав програму резервного копіювання, що називається backshift. Для початкової резервної копії, яка робить велику кількість файлів, Pypy чудово підходить. Але для подальших резервних копій, які в основному є лише оновленням часових позначок, CPython швидше.
dstromberg

Відповіді:


657

ПРИМІТКА: PyPy є більш зрілим і краще підтримується зараз, ніж це було у 2013 році, коли це питання було задано. Уникайте робити висновки із застарілої інформації.


  1. PyPy, як і інші поспішили відзначити, має слабку підтримку розширень C . Він має підтримку, але, як правило, з меншою швидкістю, ніж на 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 часто вимагає переобладнання, що для деяких людей та організацій - це просто занадто велика робота.

Я б сказав, що це основні причини, які впливають на мене.


14
Приємно, що ви згадуєте про переобладнання. Наприклад, мій веб-хост має вибір між Python 2.4 та 2.5; і "великий виробник розважального програмного забезпечення" поруч зі мною використовує 2.6, але не планує незабаром оновити. Іноді це може бути великим, дорогим зусиллям, щоб навіть виявити вартість конверсії.
Майк Госкі

19
Будучи PyPy "таким же швидким, як C", це скоріше загальний C, ніж високооптимізована багатопотокована кеш-бібліотека C, що використовується для числення. Для числових даних Python просто використовується для перевезення навколо покажчиків до великих масивів. Отже, будучи PyPy "швидким як C", це означає, що "ваші вказівники + метадані переміщаються так само швидко, як C". Не велике діло. Тоді навіщо взагалі турбуватися з Python? Перегляньте підписи функцій у cblas та lapacke.
cjordan1

12
@ cjordan1: Я не розумію, що ти кажеш. Конструкти високого рівня є надзвичайно виразними ( 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 для менших інтенсивних циклів є загальною та корисною стратегією.
Ведрак

26
@Veedrac Це я мав на увазі. Як і в "Перегляньте підписи функцій в cblas і lapacke", оскільки вони настільки довгі і важкі у використанні, що ви відразу зрозумієте, чому ми використовуємо Python для переправи навколо покажчиків і метаданих.
cjordan1

5
@ tommy.carstensen Це насправді не найкраще місце, щоб заглибитись, але я спробую. 1. Це було набагато правдивіше, коли я це писав, ніж зараз. 2. "Сценарії" часто важкі для IO. IO PyPy все ще часто повільніше, ніж CPython - раніше він був значно повільнішим. 3. PyPy раніше був повільнішим за CPython при обробці струн - тепер це часто краще і рідше гірше. 4. Багато "сценаріїв" є лише клейовим кодом - прискорення роботи інтерпретатора не покращить загальний час виконання у цьому випадку. 5. Час розминки PyPy раніше був більшим - короткі сценарії, що працюють, рідко вдавалося створити багато гарячого коду.
Ведрак

104

Цей сайт не претендує на PyPy в 6,3 рази швидше, ніж на CPython. Цитувати:

Геометричне середнє значення всіх орієнтирів у 0,16 або 6,3 рази швидше, ніж CPython

Це зовсім інше твердження до заявки, яку ви зробили, і коли ви зрозумієте різницю, ви зрозумієте принаймні одну сукупність причин, чому ви не можете просто сказати «використовувати PyPy». Це може здатися так, що я збираю нитки, але розуміння того, чому ці дві заяви абсолютно різні, є життєво важливим.

Щоб розбити це:

  • Звернення, яке вони роблять, стосується лише тестів, які вони використовували. Це не говорить абсолютно нічого про вашу програму (якщо тільки ваша програма точно не відповідає одному з їх орієнтирів).

  • Твердження стосується приблизно середнього показника групи орієнтирів. Немає тверджень, що запуск PyPy дозволить покращити в 6,3 рази навіть для тестованих програм.

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


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, ймовірно, ніколи не буде еталонною реалізацією, але це хороший інструмент.


2
Згідно з pypy.org/download.html , PyPy для компіляції потребує 4 ГБ оперативної пам’яті (у 64-бітній системі), а не 8. І на цій сторінці є можливість зробити це у 3 Гб, якщо потрібно.
knite

4
@knite 1: це нове, станом на 2015 рік, в документації історично прочитано 8 ГБ. 2: на практиці у 2015 році вам все одно потрібно щонайменше 8, з 6-7 безкоштовними.
Tritium21

4
Вимога пам'яті для компіляції не настільки актуальна, якщо ви використовуєте збірку або дистрибутив . Щодо "рухомої цілі, і дуже експериментальної", чи можете ви навести пару прикладів речей, які ламаються? Знову ж таки, якщо люди використовують версії версій, а не нічні збірки чи джерело, чи не мають вони розумного очікування функціональності?
smci

@smci Це стародавнє запитання, засноване на давніх даних, з давніми відповідями. Вважайте це питання та кожну відповідь історичними для стану піпі 4 роки тому.
Tritium21

1
@ Tritium21: Мене цікавить лише поточна відповідь. Що це? Ви можете відредагувати свою відповідь, сказавши "Станом на 2013 рік, порівнюючи pypy з версією 2.x Python було ..." Також, якщо "6,3-кратне геометричне середнє" твердження у цьому питанні застаріло ( як від 4/2017 вони вимагають 7,5x, але навіть тоді це залежить від орієнтирів ... ), то і для цього потрібно редагувати (номери версій, останні дані тощо). Я думаю, що набір тестів не дуже актуальний, навряд чи хтось би запускався в даний час промінь на мові сценаріїв на процесорі. Я знайшов pybenchmarks.org
smci

37

На друге питання простіше відповісти: ви в основному можете використовувати PyPy як заміну, якщо весь ваш код є чистою Python. Однак багато широко використовувані бібліотеки (включаючи частину стандартної бібліотеки) написані на С та складені як розширення Python. Деякі з них можна змусити працювати з PyPy, а деякі не можуть. PyPy надає той же інструмент, що спрямований вперед, як і Python --- тобто, це Python ---, але його внутрішні місця відрізняються, тому інструменти, що взаємодіють із цими внутрішніми, не працюватимуть.

Щодо першого питання, я думаю, що це свого роду Catch-22 з першим: PyPy стрімко розвивається, прагнучи покращити швидкість і підвищити сумісність з іншим кодом. Це зробило його більш експериментальним, ніж офіційним.

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


17
Я не думаю, що C - це мова, яка незабаром збирається куди завгодно (я б хотів сказати, що вона не зникне протягом нашого життя). поки не з’явиться інша мова, яка буде працювати де завгодно, у нас буде C. (зауважте, JVM написаний на C. Навіть java, мові, яка "працює всюди", потрібна C для її всюди.) його пунктів.
Tritium21

7
@ Tritium21: Так, я просто редагую там. Я добре з існуючим C, але я вважаю, що залежність Python від C надзвичайно згубна, і PyPy - чудовий приклад того: зараз у нас є шанс отримати більш швидкий Python, але нас спокушають роки, покладаючись на C . Пітону було б набагато краще стояти на двох ногах. Це навіть добре, якщо сам Python написаний на C, але проблема полягає у існуванні механізму розширення, який спонукає людей поширювати Python способами, які залежать від C.
BrenBarn

4
Меч з подвійним ребром на цьому - частина того, що зробило python настільки популярним, це його здатність розширювати інші програми та розширюватися іншими програмами. Якщо ви це заберете, я не думаю, що ми б говорили про пітона.
Tritium21

10
@BrenBarn Дуже безглуздо стверджувати, що залежність Пітона від 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 і зберігає повний інтерфейс модуля С. Я не знайшов жодної переваги щодо використання PyPy у такому випадку.


1
У PyPy є багато, ретельно запускаються орієнтири (на відміну від CPython, на жаль, на даний момент насправді немає набору орієнтованих на користувача). Звичайно, для мережевого трафіку PyPy не може магічно зробити щось швидше.
Джуліан

1
Джуліан, варто відзначити, що люди PyPy вже багато років спрямовують багато зусиль на покращення термінів виконання цього конкретного набору. В якійсь мірі здається, що вони "переозброюють" свої оптимізації для цього набору орієнтирів і, на моєму досвіді, окрім чисто числових обчислень (які в кращому випадку краще у Fortran чи C99), я ніколи не отримував PyPy бути більше ніж ~ 2X швидше, ніж CPython.
Алекс Рубінштейн

9
@AlexRubinsteyn Але погляд тих, хто працює над PyPy, завжди був таким, що якщо ви знайдете випадок, коли PyPy повільніше CPython, і ви можете перетворити його на розумний орієнтир, він має хороші шанси бути доданим до набору.
gsnedders

1
Я перевірив ваш блог. У ваших результатах пара простого пітона (маринований, StringIO) показує, що pypy на 6,8 разів швидший за cpython. Я думаю, що це корисний результат. У висновку ви вказуєте (правильно), що pypy-код (який є звичайним python!) Повільніше, ніж код C (cPickle, cStringIO), а не cpython-код.
Калеб Хаттінг

1
@gsnedders я запропонував тест , заснований на rinohtype в декількох випадках . Вони ще не додали його до набору.
Brecht Machiels

12

Питання: Якщо PyPy може вирішити ці великі проблеми (швидкість, споживання пам’яті, паралелізм) порівняно з CPython, то які його слабкі сторони заважають більш широкому впровадженню?

Відповідь: По-перше, мало свідчень того, що команда PyPy в цілому може вирішити проблему швидкості . Багаторічні дані свідчать про те, що PyPy виконує певні коди Python повільніше, ніж CPython, і цей недолік, схоже, закорінений дуже глибоко в PyPy.

По-друге, поточна версія PyPy споживає набагато більше пам’яті, ніж CPython у досить великому наборі випадків. Тож PyPy ще не вирішив проблеми споживання пам'яті.

Чи вирішує PyPy згадані великі виклики і чи буде взагалі швидше, менше голодної пам’яті та більш прихильним до паралелізму, ніж CPython, - це відкрите питання, яке не може бути вирішено за короткий термін. Деякі люди роблять ставку, що PyPy ніколи не зможе запропонувати генерала рішення, що дозволяє йому домінувати у CPython 2.7 та 3.3 у всіх випадках.

Якщо PyPy вдасться бути кращим за CPython в цілому, що сумнівно, головною слабкістю, що впливає на його більш широке прийняття, буде його сумісність із CPython. Існують також такі питання, як те, що CPython працює на більш широкому діапазоні процесорів і ОС, але ці питання є набагато менш важливими порівняно з цілями продуктивності PyPy та сумісністю з CPython.


Питання: Чому я не можу зараз відмовитися від заміни CPython на PyPy?

Відповідь: PyPy не на 100% сумісний із CPython, оскільки він не імітує CPython під кришкою. Деякі програми все ще можуть залежати від унікальних особливостей CPython, які відсутні в PyPy, таких як C прив'язки, C реалізації об'єктів і методів Python або додаткового характеру збирача сміття CPython.


Ця відповідь не цитує жодних орієнтирів і не дає посилань.
qwr

7

CPython має підрахунок довідок та збирання сміття, PyPy має лише сміття.

Тому об'єкти, як правило, видаляються раніше і __del__ викликаються більш передбачувано в CPython. Деяке програмне забезпечення покладається на таку поведінку, тому вони не готові до переходу на PyPy.

Деякі інші програми працюють з обома, але використовують менше пам'яті з CPython, оскільки невикористані об'єкти звільняються раніше. (У мене немає жодних вимірювань, які б свідчили про те, наскільки це важливо і які інші деталі реалізації впливають на використання пам'яті.)


17
Слід підкреслити, що покладатися на __del__те, щоб викликати рано чи взагалі неправильно, навіть у CPython. Як ви говорите, це зазвичай працює, і деякі люди вважають, що це гарантовано. Якщо щось, що посилається на об'єкт, потрапило в еталонний цикл (що досить легко - чи знали ви, що перевірка поточного винятку певним чином, не створюється еталоном?) Доопрацювання затримується на невизначений термін, до наступного циклу GC (що може бути ніколи ). Якщо об'єкт сам є частиною еталонного циклу, __del__не буде викликати взагалі (до Python 3.4).

3
Накладні витрати на один об'єкт вище в CPython, що має значення ЛОТ, коли ви починаєте створювати багато об'єктів. Я вважаю, що PyPy робить еквівалент слотів за замовчуванням для одного.

4

Для багатьох проектів фактично різниця 0% між різними пітонами за швидкістю. Це ті, в яких переважає інженерний час і де всі пітони мають однаковий обсяг бібліотечної підтримки.


1
Якщо ваш проект настільки простий, то, очевидно, це не має значення, але те саме можна сказати і про будь-яку реалізацію будь-якої мови: якщо все, що ви робите, - це об'єднання функцій інших бібліотек через відносно виконані ABI, то це все не має значення.

1
Це не має нічого спільного з простим. В інженерний час цикл зворотного зв'язку важливий. Іноді набагато важливіше, ніж час виконання.
Стефан Еггермон

1
Ну, ви говорите дуже розпливчасто (інженерний час без посилання на те, що розробляється, які обмеження і т. Д.; Цикл зворотного зв’язку без посилання на те, що передається кому назад і т. Д.), Тож я йду ухилятися від цієї розмови, а не торгувати криптовалютами.

Тут нічого неясного. Погляньте на цикл OODA або PDCA.
Стефан Еггермонт

3
@user Добре, що будь-який запуск одного разу, який потребує місяця, і хвилина запуску, матиме загальну швидкість на 0,0% (використання 1 місяця + 1 хвилина проти 1 місяця) від використання PyPy, навіть якщо PyPy був у тисячу разів швидшим. Стівен не стверджував, що всі проекти будуть на 0% швидше.
gmatht

4

Щоб зробити це просто: PyPy забезпечує швидкість, якої не вистачає CPython, але жертвує її сумісністю. Більшість людей, однак, вибирають Python за його гнучкість та функцію "включена батарея" (висока сумісність), а не за швидкістю (все-таки все-таки бажано).


16
"включена батарея" означає велику стандартну бібліотеку , AFAIK
thepang

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 рази швидший.


Цікаво! Ще кілька порівнянь та цифр були б чудовими.
ben26941

1

У PyPy деякий час була підтримка Python 3, але згідно з цим повідомленням HackerNoon від Ентоні Шоу від 2 квітня 2018 року , 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 року, знаходиться в бета-версії.


0

Підтримувані версії Python

Щоб цитувати дзен Python :

Читання рахується.

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

Можливо, в Python 3.7 та Python 3.8 є інші функції, які є для вас більш важливими. Справа в тому, що PyPy на даний момент не підтримує Python 3.7 або Python 3.8.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.