In che modo Python compila il suo codice in C?

7

Ho letto che alcuni costrutti di Python sono più efficienti perché sono compilati in C.

link

Alcuni degli esempi usati erano map () e filter (). Mi stavo chiedendo come Python sia in grado di farlo? È generalmente interpretato, quindi come viene compilato parte del codice mentre viene interpretato un altro - e in una lingua diversa? Perché non compili tutto il resto?

    
posta Howcan 23.08.2014 - 21:16
fonte

4 risposte

6

I read that some constructs of Python are more efficient because they are compiled in C.

Non è vero.

Prima di tutto, non c'è nulla nelle specifiche del linguaggio Python che richiede che certe funzioni debbano essere implementate in una certa lingua. Un implementatore Python può scegliere di implementare qualsiasi funzione e costruzione del linguaggio in ogni caso. Ad esempio, in Jython, quelle funzioni sono implementate in Java, non in C. In IronPython, sono implementate in C #. In PyPy, potrebbero essere implementati in RPython o solo in Python. In Pynie, sono probabilmente implementati in Python.

In secondo luogo, non c'è nulla nelle specifiche del linguaggio C che dice che deve essere compilato. Ci sono interpreti per C.

In terzo luogo, solo perché è in C non significa che sia veloce. Ci sono compilatori C là fuori che producono codice veramente terribile, e ci sono implementazioni Python piuttosto veloci.

E in quarto luogo, anche se la funzione implementata in C è incredibilmente veloce, ciò non si traduce necessariamente in una maggiore velocità di esecuzione del programma generale. Le ottimizzazioni in genere non funzionano tra le lingue. Ad esempio, l'ottimizzatore non può inline la chiamata a map nel tuo programma, perché il tuo programma è scritto in Python ma map è scritto in C. Ma l'inlining è praticamente il fondamento di tutte le ottimizzazioni, perché inlining (e ciclo di srotolamento) danno bei percorsi dritti e lunghi di codice senza rami o chiamate, che è ciò che gli ottimizzatori amano .

It's generally interpreted,

In realtà, tutte le implementazioni Python attualmente esistenti compilano sempre codice Python, non lo interpretano mai.

Why not just compile the whole thing?

Questa è una buona domanda! Scrivere tutto nella stessa lingua ha molti vantaggi, alcuni dei quali ho delineato sopra. (Un altro è che è più facile trovare collaboratori che conoscono una lingua rispetto a due.)

Se tutto è scritto nella stessa lingua, i miglioramenti delle prestazioni in quella lingua vengono moltiplicati nell'intero sistema. Se tutto è scritto in C, rendere il Python 10 volte più veloce non accelera molto il tuo programma, perché la maggior parte del codice non è Python. Certo, il codice che hai scritto è in esecuzione 10 volte più veloce, ma questo codice consiste principalmente di chiamate a funzioni C che hanno la stessa velocità di prima.

Ma se tutto è scritto in Python, quindi rendere Python più veloce avrà un effetto a catena: i tipi primitivi diventano più veloci, le strutture create su quei tipi primitivi diventano più veloci, gli algoritmi che usano quelle strutture si velocizzano, i moduli che usano quegli algoritmi diventano più veloci e così via.

    
risposta data 23.08.2014 - 22:53
fonte
10

L'interprete stesso è scritto in C (o almeno l'implementazione di riferimento CPython è). Ciò significa che ogni funzione linguistica è implementata con una funzione C minuscola. Tutto quello che fa l'interprete è leggere il codice sorgente per scoprire quale di queste minuscole funzioni chiamare.

Questo significa che non è un problema delegare anche funzioni più complesse alle implementazioni C.

Queste funzioni non sono compilate con il tuo programma. Esistono già in forma compilata nell'interprete Python che li chiama appena li incontra nel codice sorgente.

    
risposta data 23.08.2014 - 21:28
fonte
4

Dire che sono "compilati in C" è una dichiarazione un po 'confusa. Lasciatemi riformularlo: CPython (l'implementazione più diffusa dell'interprete Python, a cui ti riferisci) è un programma in C, e quelle sono funzioni C create nell'interprete, non il codice Python che l'interprete sceglie magicamente per compilare in C.

Quando si alimenta un file .py in Python, lo analizza e converte ciascuna funzione in codice byte, cioè una forma binaria compatta delle operazioni eseguite dalla funzione. Questo viene inviato alla macchina virtuale Python, un pezzo dell'interprete che legge il bytecode e fa ciò che dice di fare.

Quando chiamate funzioni scritte in Python non succede nulla di particolare: la VM salterà semplicemente a interpretare il loro bytecode; ma quando chiami una funzione che è incorporata nell'interprete, l'interprete chiama la funzione C corrispondente che ha incorporato (questo accade sempre, ad esempio la maggior parte delle operazioni sui tipi primitivi vengono effettivamente eseguite dal codice compilato direttamente nell'interprete) ).

Le funzioni scritte in C in CPython sono generalmente più veloci, sia perché sono scritte in un linguaggio che è adattato per alte prestazioni, compilato in codice nativo (non c'è bisogno di un interprete, gira direttamente sulla CPU) e ha più semplice, meno semantica dinamica (ad esempio, in Python ogni accesso a un membro è una ricerca complessa di hashtable, in C può ridursi a una singola istruzione di assemblaggio).

It's generally interpreted, so how does some of the code get compiled while another is interpreted - and in a different language? Why not just compile the whole thing?

Sembra che tu pensi che sia l'interprete a decidere quale codice viene compilato e cosa viene interpretato; questa è una premessa sbagliata. Le parti compilate sono codice che è scritto direttamente in C dagli sviluppatori CPython , ed è compilato all'interno dell'interprete quando viene costruito l'interprete (altro codice scritto in C o altri linguaggi compilati può essere chiamato da Python se è compilato in estensioni Python o tramite ctype). Tutto quello che l'interprete CPython può fare quando esegui è solo per interpretare Python e chiamare le funzioni C già pronte.

    
risposta data 24.08.2014 - 03:38
fonte
3

Non è "compilato in C" di per sé: map e filter sono funzioni integrate dalla libreria standard, che è fornita dall'implementazione del linguaggio (in questo caso, CPython). Poiché CPython è scritto in C, può facilmente implementare una qualsiasi delle sue funzioni primitive in C, se necessario.

    
risposta data 23.08.2014 - 21:28
fonte