Perché non esiste un compilatore Python per il codice macchina nativo?


25

A quanto ho capito, la causa della differenza di velocità tra i linguaggi compilati e python è che il primo compila il codice fino al codice della macchina nativa, mentre python si compila in bytecode python, per essere interpretato dal PVM. Vedo che in questo modo i codici Python possono essere utilizzati su più sistemi operativi (almeno nella maggior parte dei casi), tuttavia non capisco, perché non esiste un compilatore aggiuntivo (e facoltativo) per Python, che compila allo stesso modo dei compilatori tradizionali . Ciò lascerebbe al programmatore la scelta, il che è più importante per loro; eseguibilità multipiattaforma o prestazioni su macchine native. In generale; perché non ci sono lingue che potrebbero comportarsi sia come compilate che interpretate?


4
C'è . Haskell può anche comportarsi come compilato o interpretato attraverso GHCI
toasted_flakes

C ++ ha anche interpreti . E probabilmente tonnellate di altre lingue hanno entrambe le implementazioni.
Claudio,

2
In realtà, scegliendo IronPythong ( ironpython.net ) e compilare il codice IL prodotta utilizzando "ngen" ( msdn.microsoft.com/de-de/library/6t9t5wcf%28v=vs.110%29.aspx ) c'è un modo per compilare Python in codice macchina nativo. Non che avessi testato quella catena di utensili.
Doc Brown,

10
Si possono scrivere compilatori da Python a quelli nativi. Non sono molto interessanti perché in realtà non migliorano le prestazioni con un margine significativo, a meno che non implementino un linguaggio che assomigli a Python ma sia molto più limitato. In precedenza ho spiegato altrove perché.

Risposte:


29

No. Il motivo per cui ci sono differenze di velocità tra linguaggi come Python e C ++ è perché i linguaggi tipizzati staticamente forniscono al compilatore tonnellate di informazioni sulla struttura del programma e dei suoi dati che gli consentono di ottimizzare sia i calcoli che l'accesso alla memoria. Poiché C ++ sa che la variabile è di tipo int, può determinare il modo ottimale per manipolare quella variabile anche prima dell'esecuzione del programma. D'altra parte, in Python il runtime non sa quale sia il valore di una variabile fino a quando l'interprete non raggiunge la linea. Questo è estremamente importante per le strutture, dove in C ++ il compilatore può facilmente dire la dimensione della struttura e ogni posizione dei suoi campi nella memoria durante la compilazione. Ciò gli conferisce un enorme potere nel prevedere come i dati potrebbero essere utilizzati e consente di ottimizzare in base a tali previsioni.

Per compilare in modo efficace linguaggi come Python dovresti:

  1. Assicurarsi che la struttura dei dati sia statica durante l'esecuzione del programma. Questo è problematico perché Python ha eval e metaclassi. Entrambi che consentono di modificare la struttura del programma in base all'input del programma. Questa è una delle cose che danno a Python un tale potere espressivo.
  2. Inferire i tipi di tutte le variabili, strutture e classi dal codice sorgente stesso. Sebbene sia possibile in una certa misura, il sistema di tipo statico e l'algoritmo sarebbero così complessi che sarebbe quasi impossibile da implementare in modo utilizzabile. Potresti farlo per un sottoinsieme della lingua, ma sicuramente non per l'intero set di funzionalità linguistiche.

6
Vale la pena notare che questo rende il problema difficile , ma non impossibile. sbcl compila Common Lisp che è anche dinamico, ha evale un sacco di altre cose per rendere tristi gli autori di compilatori. Non è al livello di gcc, ma è certamente più veloce dell'interprete di CPython.
Daniel Gratzer,

3
@jozefg Ho detto compilare in modo efficace. Non solo compilare. Anche Python ha il compilatore Cython che produce codice nativo. Il punto è che quei compilatori non possono fare nemmeno una frazione delle ottimizzazioni che i compilatori per i linguaggi tipizzati staticamente possono fare. E quando confronti le prestazioni, confrontale con C ++ compilato e non interpretato Python.
Euforico

2
Bene, in realtà rimarrai sorpreso di ciò che sbcl può fare. Il gioco dei benchmark mostra che funziona veloce come Java, quasi quanto GHC, e da 1x a 10x di C. Non è lento per nessuno standard. Sì, i tipi dinamici inibiscono la compilazione in una certa misura, ma non tanto quanto sembri pensare.
Daniel Gratzer,

3
Confrontare la velocità di Python interpretato con Python compilato è interessante in sé. Smetti di dire "usa C ++". Forse hai già il codice scritto in Python. Forse il codice è più facile da scrivere in Python. Che importa. Quello che mi interessa è una velocità 1,5x (qualunque cosa sia). Questo può fare un'enorme differenza.
Thomas Eding,

3
In altre parole, se vuoi compilare, scegli un'altra lingua che è sintonizzata per questo, come C ++ o Pascal.
Please_Dont_Bully_Me_SO_Lords,

0

Due concetti potrebbero aiutarci a capire meglio perché Python compilato con il codice macchina nativo "potrebbe" non funzionare così velocemente come il C compilato o altri linguaggi comunemente compilati. Sono chiamati associazione anticipata e associazione tardiva.

Dovrei iniziare dicendo che non sono un esperto di Python e sono venuto su questo sito per caso. Ma mi piace questo sito.

Come menzionato in un'altra risposta qui, il compilatore C ++ può sapere molto sul programma e prendere decisioni su quali operazioni usare per specifiche strutture di dati. Ad esempio, se è necessario sommare due variabili intere, il compilatore sa che sono numeri interi nativi, ad esempio larghi 32 bit e può aggiungerli insieme con un'istruzione "ADD". Quindi compila l'istruzione ADD nel codice. È bloccato e non può essere modificato mentre il programma è in esecuzione. Questo è un legame precoce.

D'altra parte, in un linguaggio come Python, potremmo aspettarci che il programma generi diversi tipi di dati in modi complessi. Ora il compilatore non sa se le nostre 2 variabili sono numeri interi, float, stringhe o liste. Quindi deve compilare il codice che determina tali informazioni in fase di esecuzione e selezionare l'operazione corretta mentre il programma è in esecuzione. Questo è in ritardo e possiamo capire che ci sarà un impatto sulle prestazioni per fare quel lavoro extra mentre il programma è in esecuzione. È il prezzo da pagare per mantenere aperte queste opzioni in una lingua come Python, ma offre la massima flessibilità di runtime.


-4

Penso che abbia più a che fare con le specifiche di Python stesso, lo stesso motivo per cui non è possibile compilare C # in codice macchina. Le specifiche della lingua renderebbero i tuoi programmi buggy anche se fosse possibile a causa della natura della lingua. Perché non imparare semplicemente il linguaggio C? È molto più semplice di C ++ e leggermente avanzato rispetto a Python ma comunque accessibile.


5
C # può andare direttamente al codice macchina: Common Intermediate Language: Ahead of Time compilation - "Anche gli ambienti di esecuzione compatibili con CLI hanno la possibilità di eseguire una compilazione Ahead-of-time (AOT) di un assembly per renderlo più veloce rimuovendolo il processo JIT in fase di esecuzione. In .NET Framework è disponibile uno strumento speciale chiamato Native Image Generator (NGEN) che esegue AOT. In Mono esiste anche un'opzione per eseguire AOT. "
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.