Perché non dovrei usare PyPy su CPython se PyPy è 6,3 volte più veloce?


685

Ho sentito molto parlare del progetto PyPy . Affermano che è 6,3 volte più veloce dell'interprete CPython sul loro sito .

Ogni volta che parliamo di linguaggi dinamici come Python, la velocità è uno dei problemi principali. Per risolvere questo, dicono che PyPy è 6,3 volte più veloce.

Il secondo problema è il parallelismo, il famigerato Global Interpreter Lock (GIL). Per questo, PyPy dice che può dare Python senza GIL .

Se PyPy è in grado di risolvere queste grandi sfide, quali sono i suoi punti deboli che impediscono un'adozione più ampia? Vale a dire, cosa impedisce a qualcuno come me, un tipico sviluppatore di Python, di passare a PyPy in questo momento ?


30
Commenti eliminati perché la maggior parte erano cose che avrebbero dovuto essere arricchite di risposte (e in alcuni casi lo sono), o che non avrebbero dovuto dirle affatto. Edito anche per rispondere a un paio di preoccupazioni sollevate riguardo alla soggettività di questa domanda. Prova a rispondere usando i fatti e, se possibile, esegui il backup delle affermazioni con le fonti!
Shog9

3
Ho usato molto Pypy. Tende a funzionare molto bene. Tuttavia, mentre Pypy è un po 'più veloce per molti carichi di lavoro pesanti per CPU, in realtà è più lento per i carichi di lavoro pesanti di I / O che ho lanciato. Ad esempio, ho scritto un programma di backup deduplicato chiamato backshift. Per un backup iniziale, che fa molti blocchi di file, pypy è fantastico. Ma per i backup successivi che stanno principalmente aggiornando i timestamp, CPython è più veloce.
dstromberg,

Risposte:


657

NOTA: PyPy è più maturo e meglio supportato ora rispetto al 2013, quando è stata posta questa domanda. Evita di trarre conclusioni da informazioni non aggiornate.


  1. PyPy, come altri si sono affrettati a parlare, ha il supporto per le estensioni tenue C . Essa ha il supporto, ma in genere a velocità più lenta del Python ed è incerto al meglio. Quindi molti moduli richiedono semplicemente CPython. PyPy non supporta numpy PyPy ora supporta numpy . Alcune estensioni non sono ancora supportate (Pandas, SciPy, ecc.), Dai un'occhiata all'elenco dei pacchetti supportati prima di apportare la modifica.
  2. Il supporto di Python 3 è attualmente sperimentale. ha appena raggiunto la stabilità! A partire dal 20 giugno 2014, PyPy3 2.3.1 - Fulcrum è uscito !
  3. PyPy a volte non è in realtà più veloce per gli "script", per cui molte persone usano Python. Questi sono i programmi a esecuzione breve che fanno qualcosa di semplice e piccolo. Poiché PyPy è un compilatore JIT, i suoi principali vantaggi derivano da tempi di esecuzione lunghi e tipi semplici (come i numeri). Francamente, le velocità pre-JIT di PyPy sono piuttosto scarse rispetto a CPython.
  4. Inerzia . Passare a PyPy richiede spesso il riattrezzaggio, che per alcune persone e organizzazioni è semplicemente troppo lavoro.

Quelli sono i motivi principali che mi riguardano, direi.


14
Bello che tu abbia citato il riattrezzaggio. Il mio host web, ad esempio, ha una scelta tra Python 2.4 e 2.5; e un "grande produttore di software di intrattenimento" vicino a me sta usando 2.6 senza piani di aggiornamento a breve. A volte può essere uno sforzo importante e costoso persino scoprire il costo di una conversione.
Mike Housky,

19
Il fatto che PyPy sia "più veloce di C" riguarda più le C generiche che le librerie C multithread altamente ottimizzate per la cache utilizzate per i valori numerici. Per i valori numerici, Python viene utilizzato solo per agganciare i puntatori a grandi array. Quindi PyPy essendo "veloce come C" significa "i tuoi puntatori + metadati vengono spostati velocemente come C". Non un grande affare. Allora perché preoccuparsi di Python? Guarda le firme delle funzioni in cblas e lapacke.
cjordan1,

12
@ cjordan1: non capisco quello che stai dicendo. I costrutti intorpiditi di alto livello sono estremamente espressivi ( np.sum(M[1:2*n**2:2, :2*n**2] * M[:2*n**2:2, :2*n**2].conjugate(), axis=1)?) In Python e ciò rende Python molto adatto alla comunità scientifica. Inoltre, eseguire le parti non intensive in Python e sborsare verso C per i loop intensivi più piccoli è una strategia comune e utilizzabile.
Veedrac,

26
@Veedrac Ecco cosa intendevo. Come in "Vai a guardare le firme delle funzioni in cblas e lapacke" perché sono così lunghe e difficili da usare che capirai immediatamente perché usiamo Python per aggirare puntatori e metadati.
cjordan1,

5
@ tommy.carstensen Questo non è davvero un buon posto per approfondire, ma ci proverò. 1. Questo è stato molto più vero quando l'ho scritto di quanto non lo sia ora. 2. Gli "script" sono spesso pesanti per IO. L'IO di PyPy è ancora spesso più lento di quello di CPython - era significativamente più lento. 3. PyPy era più lento di CPython nella gestione delle stringhe - ora è spesso migliore e raramente peggiore. 4. Molti "script" sono solo codici di colla - rendendo l'interprete più veloce in questo caso non migliorerà l'autonomia complessiva. 5. I tempi di riscaldamento di PyPy erano più grandi: gli script di breve durata raramente riuscivano a produrre molto hot code.
Veedrac,

104

Quel sito non afferma che PyPy è 6,3 volte più veloce di CPython. Per citare:

La media geometrica di tutti i benchmark è 0,16 o 6,3 volte più veloce di CPython

Questa è un'affermazione molto diversa dall'affermazione generale che hai fatto e quando capisci la differenza, capirai almeno una serie di motivi per cui non puoi semplicemente dire "usa PyPy". Potrebbe sembrare che io sia pignolo, ma capire perché queste due affermazioni sono totalmente diverse è vitale.

Per scomporlo:

  • La dichiarazione che fanno si applica solo ai parametri di riferimento che hanno usato. Non dice assolutamente nulla sul tuo programma (a meno che il tuo programma non sia esattamente lo stesso di uno dei loro benchmark).

  • La dichiarazione è circa una media di un gruppo di parametri di riferimento. Non si afferma che eseguire PyPy migliorerà 6,3 volte anche per i programmi che hanno testato.

  • Non v'è alcuna pretesa che PyPy sarà anche eseguire tutti i programmi che CPython corre a tutti , per non parlare più velocemente.


15
Ovviamente non si può affermare che PyPy eseguirà tutto il codice Python più velocemente. Ma se prendi tutte le applicazioni Python pure, posso scommettere che la maggior parte di esse funzionerà molto più velocemente (> 3 volte) su PyPy e poi su CPython.
Robert Zaremba,

18
Nessuno dei tuoi primi due punti elenco ha senso. Come puoi dire che i benchmark dicono "assolutamente nulla del tuo programma". È abbastanza ovvio che i benchmark non sono un indicatore perfetto di tutte le applicazioni reali, ma possono sicuramente essere utili come indicatore. Inoltre non capisco cosa trovi fuorviante nel riferire la media di un gruppo di benchmark. Dichiarano abbastanza chiaramente che è una media. Se un programmatore non capisce cosa sia una media, allora ha preoccupazioni molto più serie delle prestazioni linguistiche.
Sean Geoffrey Pietz,

6
@SeanGeoffreyPietz - Non stavo sostenendo che il sito di PyPy fosse in qualche modo fuorviante - hanno presentato i loro risultati in modo accurato. Ma la domanda originale li ha citati in modo errato e stava dimostrando che l'autore non capiva l'importanza della parola "media". Molti dei singoli benchmark non sono 6.3 volte più veloci. E se usi un diverso tipo di media ottieni un valore diverso, quindi "6,3 volte più veloce" non è un riassunto adeguato di "la media geometrica è 6,3 volte più veloce". "Il gruppo A è Z volte più veloce del gruppo B" è troppo vago per essere significativo.
spookylukey,

6
-1: @spookylukey Sembri suggerire che la suite di benchmark sia distorta senza fornire prove a sostegno del reclamo. Le critiche dovrebbero sempre essere supportate da prove!
Evgeni Sergeev,

5
@EvgeniSergeev - no, sto insinuando che tutti i benchmark sono distorti! Non necessariamente deliberatamente, ovviamente. Lo spazio di possibili programmi utili è infinito e incredibilmente vario, e una serie di parametri di riferimento misura sempre e solo le prestazioni su tali parametri. Chiedere "quanto è più veloce PyPy di ​​CPython?" è come chiedere "quanto più velocemente se Fred che Joe?", che è ciò che l'OP sembra voler sapere.
spookylukey,

74

Poiché pypy non è compatibile al 100%, richiede 8 GB di ram per essere compilato, è un obiettivo mobile e altamente sperimentale, in cui cpython è stabile, l'obiettivo predefinito per i costruttori di moduli per 2 decenni (incluse estensioni c che non funzionano su pypy ) e già ampiamente utilizzato.

Pypy probabilmente non sarà mai l'implementazione di riferimento, ma è un buon strumento da avere.


2
Secondo pypy.org/download.html , PyPy ha bisogno di 4 GB di RAM per compilare (su un sistema a 64 bit), non 8. E c'è un'opzione su quella pagina per farlo sotto i 3 GB, se necessario.
Knite

4
@knite 1: novità dal 2015, la documentazione ha storicamente letto 8 GB. 2: in pratica nel 2015 hai ancora bisogno di almeno 8, con 6-7 gratuiti.
Tritium21

4
Il requisito di memoria da compilare non è così rilevante se si utilizza una build o una distribuzione . Quanto al "bersaglio mobile e altamente sperimentale", puoi dare un paio di esempi di cose che si rompono? Ancora una volta, se le persone usano build di rilascio piuttosto che build o sorgenti notturne, non hanno una ragionevole aspettativa di funzionalità?
smci,

@smci Questa è un'antica domanda basata su dati antichi, con risposte antiche. Considera questa domanda e ogni risposta come storica per lo stato di pypy 4 anni fa.
Tritium21,

1
@ Tritium21: sono interessato solo alla risposta attuale. Che cos'è? Potresti modificare la risposta per dire "A partire dal 2013, il confronto tra pypy e la versione 2.x di Python era ..." Anche se l'affermazione "6.3x geometrica media" nella domanda non è aggiornata ( come del 4/2017 dichiarano 7.5x, ma anche allora dipende dai benchmark ... ), quindi anche questo ha bisogno di essere modificato (numeri di versione, dati più recenti, ecc.) Penso che la suite di benchmark non sia molto pertinente, quasi nessuno avrebbe eseguito oggigiorno raytracing in un linguaggio di scripting su una CPU. Ho trovato pybenchmarks.org
smci il

37

Alla seconda domanda è più facile rispondere: in pratica puoi usare PyPy come sostituto drop-in se tutto il tuo codice è Python puro. Tuttavia, molte librerie ampiamente utilizzate (incluse alcune delle librerie standard) sono scritte in C e compilate come estensioni di Python. Alcuni di questi possono essere fatti funzionare con PyPy, altri no. PyPy fornisce lo stesso strumento "rivolto in avanti" di Python --- cioè è Python --- ma le sue viscere sono diverse, quindi gli strumenti che si interfacciano con quelle viscere non funzioneranno.

Per quanto riguarda la prima domanda, immagino che sia una specie di Catch-22 con la prima: PyPy si è evoluto rapidamente nel tentativo di migliorare la velocità e migliorare l'interoperabilità con altri codici. Ciò lo ha reso più sperimentale che ufficiale.

Penso che sia possibile che se PyPy si trova in uno stato stabile, potrebbe iniziare ad essere più ampiamente utilizzato. Penso anche che sarebbe fantastico per Python allontanarsi dalle sue basi in C. Ma non succederà per un po '. PyPy non ha ancora raggiunto la massa critica in cui è quasi abbastanza utile da solo fare tutto ciò che desideri, il che motiverebbe le persone a colmare le lacune.


17
Non credo che C sia una lingua che presto andrà ovunque (sarei disposto a dire che non scomparirà nella nostra vita). fino a quando non ci sarà un'altra lingua che funzionerà ovunque, avremo C. dei suoi punti.
Tritium21

7
@ Tritium21: Sì, sto solo pubblicando lì. Sto bene con C esistente, ma penso che la dipendenza di Python da C sia estremamente dannosa e PyPy è un ottimo esempio del perché: ora abbiamo la possibilità di ottenere Python più veloce, ma siamo inciampati da anni di affidamento su C Sarebbe molto meglio per Python stare in piedi da solo. Va anche bene se Python stesso è scritto in C, ma il problema è l'esistenza di un meccanismo di estensione che incoraggia le persone a estendere Python in modi che dipendono da C.
BrenBarn

4
un'arma a doppio taglio su questo - parte di ciò che ha reso il pitone così popolare è la sua capacità di estendere altre applicazioni ed essere estesa da altre applicazioni. Se lo porti via, non penso che parleremmo di Python.
Tritium21

10
@BrenBarn È assolutamente folle affermare che la dipendenza di Python da C è dannosa. Senza la C-API di Python, la maggior parte delle librerie davvero potenti e la grande interoperabilità che Python ha acquisito nella sua adolescenza formativa (fine anni '90), compreso l'intero ecosistema numerico / scientifico e le interfacce GUI, non sarebbero state possibili. Guardati intorno per avere una prospettiva sull'intero universo degli usi di Python, prima di fare affermazioni così generali.
Peter Wang,

4
@PeterWang Tutte quelle librerie possono essere scritte in Python, tuttavia non sarebbero così veloci come sono. Ciò che BrenBarn sta dicendo è che ora abbiamo la possibilità di rendere Python abbastanza veloce in modo che quelle librerie possano essere scritte in Python ma ci stiamo rifiutando di cogliere questa possibilità, perché prenderlo significa perdere la capacità di usare le librerie C. Credo che questo sia ciò che intendeva per dannoso, non che l'esistenza delle librerie C è una cosa negativa, ma che l'unico modo per creare librerie veloci è usare C.
Vikki,

14

Ho fatto un piccolo punto di riferimento su questo argomento. Mentre molti degli altri poster hanno messo in evidenza la compatibilità, la mia esperienza è stata che PyPy non è molto più veloce semplicemente spostandosi sui bit. Per molti usi di Python, esiste davvero solo per tradurre bit tra due o più servizi. Ad esempio, non molte applicazioni Web stanno eseguendo un'analisi intensiva della CPU dei set di dati. Invece, prendono alcuni byte da un client, li memorizzano in una sorta di database e li restituiscono in seguito ad altri client. A volte il formato dei dati viene modificato.

Gli sviluppatori BDFL e CPython sono un gruppo di persone straordinariamente intelligenti e sono riusciti ad aiutare CPython a ottenere prestazioni eccellenti in questo scenario. Ecco un blog spudorato: http://www.hydrogen18.com/blog/unpickling-buffers.html . Sto usando Stackless, che è derivato da CPython e mantiene l'intera interfaccia del modulo C. Non ho trovato alcun vantaggio nell'usare PyPy in quel caso.


1
PyPy ha molti benchmark eseguiti con cura (a differenza di CPython sfortunatamente, che al momento non ha una suite di benchmark rivolta all'utente). Naturalmente per il traffico di rete PyPy non può magicamente fare nulla di più veloce.
Julian,

1
Julian, vale la pena notare che la gente di PyPy da molti anni concentra molti sforzi per migliorare i tempi di esecuzione di quella particolare suite di benchmark. In una certa misura sembra che stiano "adattando troppo" le loro ottimizzazioni a questo insieme di parametri di riferimento e, nella mia esperienza, a parte i calcoli puramente numerici (che sono comunque migliori in Fortran o C99), non ho mai ottenuto PyPy per essere più di ~ 2 volte più veloce di CPython.
Alex Rubinsteyn,

9
@AlexRubinsteyn Ma l'opinione di coloro che lavorano su PyPy è sempre stata generalmente che se trovi un caso in cui PyPy è più lento di CPython e puoi trasformarlo in un benchmark ragionevole, ha buone probabilità di essere aggiunto alla suite.
gsnedders,

1
Ho controllato il tuo blog. Nei tuoi risultati, la coppia plain-python di (pickle, StringIO) mostra che pypy è ~ 6,8 volte più veloce di cpython. Penso che questo sia un risultato utile. In conclusione, fai notare (correttamente) che il codice pypy (che è un semplice pitone!) È più lento del codice C (cPickle, cStringIO), non del codice cpython.
Caleb Hattingh,

1
@gsnedders Ho offerto un benchmark basato su rinohtype in più occasioni . Non l'hanno ancora aggiunto alla suite.
Brecht Machiels,

12

D: Se PyPy è in grado di risolvere queste grandi sfide (velocità, consumo di memoria, parallelismo) rispetto a CPython, quali sono i suoi punti deboli che impediscono un'adozione più ampia?

A: Innanzitutto, ci sono poche prove che il team PyPy possa risolvere il problema della velocità in generale . Le prove a lungo termine mostrano che PyPy esegue alcuni codici Python più lentamente di CPython e questo inconveniente sembra essere profondamente radicato in PyPy.

In secondo luogo, l'attuale versione di PyPy consuma molta più memoria rispetto a CPython in una serie piuttosto ampia di casi. Quindi PyPy non ha ancora risolto il problema del consumo di memoria.

Se PyPy risolve le grandi sfide menzionate e in generale sarà più veloce, meno affamato di memoria e più amichevole al parallelismo rispetto a CPython è una domanda aperta che non può essere risolta a breve termine. Alcune persone scommettono che PyPy non sarà mai in grado di offrire una soluzione generale che gli consenta di dominare CPython 2.7 e 3.3 in tutti i casi.

Se PyPy riesce a essere migliore di CPython in generale, il che è discutibile, la principale debolezza che influenza la sua adozione più ampia sarà la sua compatibilità con CPython. Esistono anche problemi come il fatto che CPython funzioni su una gamma più ampia di CPU e sistemi operativi, ma questi problemi sono molto meno importanti rispetto alle prestazioni di PyPy e agli obiettivi di compatibilità di CPython.


D: Perché non posso interrompere subito la sostituzione di CPython con PyPy?

A: PyPy non è compatibile al 100% con CPython perché non simula CPython sotto il cofano. Alcuni programmi possono ancora dipendere dalle caratteristiche uniche di CPython che sono assenti in PyPy come i collegamenti C, le implementazioni C dell'oggetto e dei metodi Python o la natura incrementale del garbage collector di CPython.


Questa risposta non cita alcun benchmark né fornisce riferimenti.
qwr

7

CPython ha il conteggio dei riferimenti e la garbage collection, PyPy ha solo la garbage collection.

Quindi gli oggetti tendono ad essere eliminati prima e __del__vengono chiamati in modo più prevedibile in CPython. Alcuni software si basano su questo comportamento, quindi non sono pronti per la migrazione a PyPy.

Alcuni altri software funzionano con entrambi, ma utilizzano meno memoria con CPython, poiché gli oggetti non utilizzati vengono liberati in precedenza. (Non ho alcuna misura per indicare quanto questo sia significativo e quali altri dettagli di implementazione influenzano l'uso della memoria.)


17
Va sottolineato che fare affidamento __del__sull'essere chiamato in anticipo o per niente è sbagliato anche in CPython. Come dici tu, di solito funziona e alcune persone pensano che sia garantito. Se qualcosa che fa riferimento all'oggetto viene coinvolto in un ciclo di riferimento (che è piuttosto semplice - sapevi che ispezionare l'eccezione corrente in un certo modo non forzato crea un ciclo di riferimento?) La finalizzazione viene ritardata indefinitamente, fino al ciclo successivo GC (che potrebbe non essere mai ). Se l'oggetto stesso fa parte di un ciclo di riferimento, __del__non verrà chiamato affatto (prima di Python 3.4).

3
Il sovraccarico per oggetto è maggiore in CPython, il che conta MOLTO una volta che inizi a creare molti oggetti. Credo che PyPy faccia l'equivalente degli slot di default, per prima cosa.

4

Per molti progetti, esiste una differenza dello 0% tra i diversi pitoni in termini di velocità. Ecco quelli che sono dominati dal tempo di ingegneria e in cui tutti i pitoni hanno la stessa quantità di supporto per la libreria.


1
Se il tuo progetto è così semplice, ovviamente non importa, ma lo stesso si potrebbe dire di qualsiasi implementazione di qualsiasi linguaggio: se tutto ciò che fai è aggregare le funzioni di altre librerie tramite ABI relativamente performanti, allora è tutto irrilevante.

1
Non ha nulla a che fare con il semplice. In fase di progettazione il circuito di feedback è importante. A volte molto più importante del tempo di esecuzione.
Stephan Eggermont,

1
Bene, stai parlando in modo molto vago (tempo di ingegnerizzazione senza riferimento a ciò che viene progettato, quali sono i vincoli, ecc .; loop di feedback senza riferimento a ciò che viene restituito a chi, ecc.), Quindi vado uscire da questa conversazione piuttosto che scambiare riferimenti criptici.

Niente di vago qui. Dai un'occhiata al loop OODA o PDCA.
Stephan Eggermont,

3
@utente Bene, qualsiasi progetto eseguito una volta che impiega un mese per scrivere e un minuto per funzionare, avrà una velocità complessiva dello 0,0% (1 mese + 1 minuto contro 1 mese) dall'uso di PyPy, anche se PyPy era mille volte più veloce. Stephan non ha affermato che tutti i progetti avrebbero una velocità dello 0%.
Gmatht

4

Per renderlo semplice: PyPy fornisce la velocità che manca a CPython ma sacrifica la sua compatibilità. La maggior parte delle persone, tuttavia, sceglie Python per la sua flessibilità e la sua funzione "batteria inclusa" (alta compatibilità), non per la sua velocità (è comunque preferibile).


16
"batteria inclusa" significa grande libreria standard , AFAIK
tshepang

4

Ho trovato degli esempi in cui PyPy è più lento di Python. Ma: solo su 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

Quindi, se pensi a PyPy, dimentica Windows. Su Linux, puoi ottenere incredibili accelerazioni. Esempio (elenca tutti i numeri primi compresi tra 1 e 1.000.000):

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

Funziona 10 (!) Volte più velocemente su PyPy che su Python. Ma non su Windows. Lì è solo 3 volte più veloce.


Interessante! Alcuni altri confronti e numeri sarebbero stati fantastici.
ben26941,

1

PyPy ha avuto il supporto di Python 3 per un po ', ma secondo questo post di HackerNoon di Anthony Shaw del 2 aprile 2018 , PyPy3 è ancora più volte più lento di PyPy (Python 2).

Per molti calcoli scientifici, in particolare i calcoli con matrici, numpy è una scelta migliore (vedi FAQ: devo installare numpy o numpypy? ).

Pypy non supporta gmpy2. Puoi invece utilizzare gmpy_cffi anche se non ho testato la sua velocità e il progetto ha avuto una versione nel 2014.

Per i problemi di Project Euler, utilizzo spesso PyPy e per semplici calcoli numerici spesso from __future__ import divisionè sufficiente per i miei scopi, ma il supporto di Python 3 è ancora in fase di elaborazione a partire dal 2018, con la tua scommessa migliore su Linux a 64 bit. Windows PyPy3.5 v6.0, l'ultimo a dicembre 2018, è in versione beta.


0

Versioni di Python supportate

Per citare lo Zen di Python :

La leggibilità conta.

Ad esempio, Python 3.7 ha introdotto i dataclass e Python 3.8 ha introdotto fstring = .

Potrebbero esserci altre funzionalità in Python 3.7 e Python 3.8 che sono più importanti per te. Il punto è che PyPy al momento non supporta Python 3.7 o Python 3.8.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.