PyPy - Come può eventualmente battere CPython?


264

Dal blog open source di Google :

PyPy è una reimplementazione di Python in Python, utilizzando tecniche avanzate per cercare di ottenere prestazioni migliori rispetto a CPython. Molti anni di duro lavoro hanno finalmente ripagato. I nostri risultati di velocità spesso battono CPython, spaziando da un po 'più lento, a velocizzazioni fino a 2 volte su un codice applicativo reale, a velocizzazioni fino a 10 volte su piccoli benchmark.

Com'è possibile? Quale implementazione di Python è stata utilizzata per implementare PyPy? CPython ? E quali sono le probabilità che un PyPyPy o PyPyPyPy battano il loro punteggio?

(In una nota correlata ... perché qualcuno dovrebbe provare qualcosa del genere?)


43
Nitpick: PyPy è PyPyPy. Pensa al prefisso Py- * come a un operatore di proiezione.
u0b34a0f6ae

Ok. quindi PyPy dovrebbe essere preferito rispetto a CPython? ha degli svantaggi?
Balki,

10
PyPy è eccellente per l'ottimizzazione del runtime, ma le sue diverse viscere lo rendono incompatibile con diverse estensioni C.
Cees Timmerman,

4
Quasi a tutti manca la domanda su come un aumento di velocità sia teoricamente possibile. Ma pensaci: Python può fare qualsiasi cosa, proprio come una macchina di Turing. Dopotutto può chiamare gcc. Quindi puoi anche scrivere del codice Python che gira su CPython, che interpreta un altro codice Python, lo traduce in C, lo esegue gcce quindi esegue il programma compilato. E potrebbe essere più veloce, se il codice viene chiamato abbastanza spesso.
osa,

Risposte:


155

Q1. Com'è possibile?

La gestione manuale della memoria (che è ciò che CPython fa con il suo conteggio) può essere più lenta della gestione automatica in alcuni casi.

Le limitazioni nell'implementazione dell'interprete CPython precludono alcune ottimizzazioni che PyPy può fare (es. Serrature a grana fine).

Come accennato da Marcelo, il JIT. Essere in grado di confermare al volo il tipo di un oggetto può farti risparmiare la necessità di fare più dereferenze del puntatore per arrivare finalmente al metodo che vuoi chiamare.

Q2. Quale implementazione di Python è stata utilizzata per implementare PyPy?

L'interprete PyPy è implementato in RPython che è un sottoinsieme tipicamente statico di Python (il linguaggio e non l'interprete CPython). - Fare riferimento a https://pypy.readthedocs.org/en/latest/architecture.html per i dettagli.

Q3. E quali sono le probabilità che un PyPyPy o PyPyPyPy battano il loro punteggio?

Ciò dipenderebbe dall'implementazione di questi ipotetici interpreti. Se uno di loro, ad esempio, prendesse il sorgente, facesse una sorta di analisi su di esso e lo convertisse direttamente in un codice assembly specifico target target dopo averlo eseguito per un po ', immagino che sarebbe molto più veloce di CPython.

Aggiornamento: Di recente, su un esempio accuratamente realizzato , PyPy ha superato un programma C simile compilato gcc -O3. È un caso inventato ma mostra alcune idee.

Q4. Perché qualcuno dovrebbe provare qualcosa del genere?

Dal sito ufficiale. https://pypy.readthedocs.org/en/latest/architecture.html#mission-statement

Miriamo a fornire:

  • un quadro comune di traduzione e supporto per la produzione di
    implementazioni di linguaggi dinamici, sottolineando una netta
    separazione tra specifiche della lingua e
    aspetti dell'implementazione . Lo chiamiamo RPython toolchain_.

  • un'implementazione conforme, flessibile e rapida del linguaggio Python_ che utilizza la toolchain di cui sopra per abilitare nuove funzionalità avanzate di alto livello senza dover codificare i dettagli di basso livello.

Separando le preoccupazioni in questo modo, la nostra implementazione di Python - e di altri linguaggi dinamici - è in grado di generare automaticamente un compilatore Just-in-Time per qualsiasi linguaggio dinamico. Consente inoltre un approccio mix-and-match alle decisioni di implementazione, incluse molte che sono state storicamente al di fuori del controllo di un utente, come piattaforma di destinazione, modelli di memoria e threading, strategie di garbage collection e ottimizzazioni applicate, incluso se avere o meno un JIT in primo luogo.

Il compilatore C gcc è implementato in C, il compilatore Haskell GHC è scritto in Haskell. Hai qualche motivo per l'interprete / compilatore Python di non essere scritto in Python?


82
A questa risposta manca completamente la spiegazione principale di come PyPy è veloce; mentre menziona che PyPy non è realmente implementato in Python, ma in RPython, non sottolinea che il codice RPython è compilato staticamente e ottimizzato per produrre l'interprete PyPy (capita anche che sia un codice Python valido che può essere eseguito in cima di CPython molto più lentamente). Ciò che hanno implementato in "Python normale" è il "compilatore" di RPython (il framework di traduzione indicato nella citazione del blocco).
Ben

12
Questo sta seppellendo il lede. Gran parte delle prestazioni proviene dalla traduzione in C (che rende l'interprete non molto più lento di CPython) e JIT, che rende i percorsi caldi molto più veloci.
Tobu,

4
"Aggiornamento: Di recente, su un esempio accuratamente realizzato, PyPy ha superato un programma C simile compilato con gcc -O3." E se leggi il primo commento sotto quel post, vedrai che lo scrittore di quel post non conosce l'ottimizzazione del tempo di collegamento. Con l'ottimizzazione del tempo di collegamento abilitata, il codice C viene eseguito più velocemente.
Ali,

2
Bene, il post sul blog era nel 2011 e questa risposta nel 2014. Inoltre, il commento menziona le librerie condivise. Non so quanto di questo (risposta e post sul blog) sia valido. Tutte le tecnologie coinvolte sono cambiate molto negli ultimi anni.
Noufal Ibrahim,

1
Sui due esempi accuratamente elaborati di Pypy più veloce dell'equivalente C, ognuno è più veloce nel benchmark per una serie molto specifica di motivi. Il primo perché Pypy è abbastanza intelligente da realizzare che il conteggio a circuito chiuso non ha mai usato quel conteggio, quindi può essere cancellato del tutto (passaggio JIT) il secondo per una combinazione di: perché il Pypy JIT può "inline oltre i confini della libreria", dato l'esempio della funzione "printf" essendo specializzato per poter letteralmente emettere solo un numero intero ed elimina malloc ripetuto (overhead di allocazione della memoria).
amcgregor,

291

"PyPy è una reimplementazione di Python in Python" è un modo piuttosto fuorviante per descrivere PyPy, IMHO, anche se tecnicamente vero.

Ci sono due parti principali di PyPy.

  1. Il framework di traduzione
  2. L'interprete

Il framework di traduzione è un compilatore. Compila il codice RPython fino a C (o altri target), aggiungendo automaticamente aspetti come garbage collection e un compilatore JIT. Non può gestire codice Python arbitrario, solo RPython.

RPython è un sottoinsieme del normale Python; tutto il codice RPython è codice Python, ma non viceversa. Non esiste una definizione formale di RPython, poiché RPython è fondamentalmente solo "il sottoinsieme di Python che può essere tradotto dal framework di traduzione di PyPy". Ma per essere tradotto, il codice RPython deve essere tipizzato staticamente (i tipi sono dedotti, non li dichiari, ma è comunque rigorosamente un tipo per variabile) e non puoi fare cose come dichiarare / modificare funzioni / classi durante l'esecuzione.

L'interprete quindi è un normale interprete Python scritto in RPython.

Poiché il codice RPython è un normale codice Python, è possibile eseguirlo su qualsiasi interprete Python. Ma nessuna delle affermazioni sulla velocità di PyPy proviene dal farlo in quel modo; questo è solo per un rapido ciclo di test, perché la traduzione dell'interprete richiede molto tempo.

Detto ciò, dovrebbe essere immediatamente ovvio che le speculazioni su PyPyPy o PyPyPyPy non hanno alcun senso. Hai un interprete scritto in RPython. Lo traduci in codice C che esegue rapidamente Python. Lì il processo si ferma; non c'è più RPython per accelerare elaborandolo di nuovo.

Quindi "Come è possibile che PyPy sia più veloce di CPython" diventa anche abbastanza ovvio. PyPy ha un'implementazione migliore, incluso un compilatore JIT (in genere non è altrettanto veloce senza il compilatore JIT, credo, il che significa che PyPy è solo più veloce per i programmi sensibili alla compilazione JIT). CPython non è mai stato progettato per essere un'implementazione altamente ottimizzante del linguaggio Python (sebbene provino a renderlo un'implementazione altamente ottimizzata , se segui la differenza).


La parte davvero innovativa del progetto PyPy è che non scrivono a mano sofisticati schemi GC o compilatori JIT. Scrivono l'interprete in modo relativamente semplice in RPython, e per tutti RPython è di livello inferiore rispetto a Python è ancora un linguaggio di raccolta dei rifiuti orientato agli oggetti, molto più alto livello di C. Quindi il framework di traduzione aggiunge automaticamente cose come GC e JIT. Quindi il framework di traduzione è enormesforzo, ma si applica ugualmente bene all'interprete PyPy Python, tuttavia modificano la loro implementazione, consentendo molta più libertà nella sperimentazione per migliorare le prestazioni (senza preoccuparsi di introdurre bug GC o aggiornare il compilatore JIT per far fronte alle modifiche). Significa anche che quando riescono a implementare un interprete Python3, otterranno automaticamente gli stessi vantaggi. E qualsiasi altro interprete scritto con il framework PyPy (di cui esiste un numero in varie fasi di polacco). E tutti gli interpreti che utilizzano il framework PyPy supportano automaticamente tutte le piattaforme supportate dal framework.

Quindi il vero vantaggio del progetto PyPy è quello di separare (il più possibile) tutte le parti dell'implementazione di un interprete efficiente indipendente dalla piattaforma per un linguaggio dinamico. E poi escogita una buona implementazione di essi in un unico posto, che può essere riutilizzato in molti interpreti. Non è una vittoria immediata come "il mio programma Python funziona più velocemente ora", ma è una grande prospettiva per il futuro.

E può eseguire il tuo programma Python più velocemente (forse).


4
Non ho potuto seguire la differenza :(
polvoazul

37
@polvoazul La differenza tra un'implementazione del linguaggio ottimizzata e un'ottimizzazione ? Bene, quando dico che CPython è un'implementazione ben ottimizzata, intendo che gli sviluppatori cercano di far funzionare in modo efficiente gli algoritmi interni dell'interprete stesso e le strutture di dati incorporate. Un'implementazione ottimizzata , OTOH, analizzerebbe il codice degli utenti finali e proverebbe a capire come trasformarlo per eseguirlo in modo più efficiente.
Ben

23

PyPy è implementato in Python, ma implementa un compilatore JIT per generare al volo codice nativo.

Il motivo per implementare PyPy su Python è probabilmente che è semplicemente un linguaggio molto produttivo, soprattutto perché il compilatore JIT rende le prestazioni del linguaggio host un po 'irrilevanti.


JIT genera codice Python in esecuzione allo stesso livello di PyPy o genera codice nativo reale in esecuzione a livello di qualunque implementazione di Python su cui PyPy è in esecuzione?
Edmund

3
Codice nativo reale (vedi qui ); Codice x86 a 32 bit per la precisione.
Marcelo Cantos

11

PyPy è scritto in Python con restrizioni. Non funziona sull'interprete CPython, per quanto ne so. Python limitato è un sottoinsieme del linguaggio Python. AFAIK, l'interprete PyPy viene compilato in codice macchina, quindi quando installato non utilizza un interprete Python in fase di esecuzione.

La tua domanda sembra aspettarsi che l'interprete PyPy sia in esecuzione su CPython durante l'esecuzione del codice. Modifica: Sì, per usare PyPy devi prima tradurre il codice Pyon PyPy, in C e compilare con gcc, in codice byte jvm o in codice CLI .Net. Vedi Introduzione


8
PyPy verrà eseguito su CPython ma in questa modalità non fornisce i guadagni di velocità che si potrebbero desiderare. :-) codespeak.net/pypy/dist/pypy/doc/…
Frank V
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.