performance - studiare - python what is




Perché le lingue interpretate sono lente? (10)

Stavo leggendo i pro ei contro delle lingue interpretate, e uno dei contro più comuni è la lentezza, ma perché i programmi nelle lingue interpretate sono lenti?


Pensa all'interprete come a un emulatore per una macchina che non hai

La risposta breve è che i linguaggi compilati sono eseguiti da istruzioni macchina mentre quelli interpretati sono eseguiti da un programma (scritto in un linguaggio compilato) che legge l'origine o un bytecode e quindi emula essenzialmente una macchina ipotetica che avrebbe eseguito il programma direttamente se la macchina esistesse.

Pensa al runtime interpretato come a un emulatore per una macchina che in realtà non hai in giro.

Questo è ovviamente complicato dai compilatori JIT (Just In Time) che Java, C # e altri hanno. In teoria, sono buoni come i compilatori "AOT" ("A una volta"), ma in pratica quei linguaggi funzionano più lentamente e sono disabilitati dal bisogno di avere il compilatore in giro consumando memoria e tempo al runtime del programma. Ma se dici qualcosa di questo qui su SO, preparati ad attirare i rabbi difensori della JIT che insistono sul fatto che non esiste alcuna differenza teorica tra JIT e AOT. Se gli chiedi se Java e C # sono veloci come C e C ++, allora iniziano a creare scuse e un po 'di calma un po'. :-)

Quindi, C ++ regola totalmente i giochi in cui la massima quantità di calcolo disponibile può sempre essere utilizzata.

Sul desktop e sul web, le attività orientate alle informazioni sono spesso eseguite in lingue con più astrazione o almeno meno compilazione, perché i computer sono molto veloci e i problemi non sono intensi dal punto di vista computazionale, quindi possiamo dedicare un po 'di tempo a obiettivi come il time-to -market, produttività del programmatore, ambienti sicuri per la memoria affidabili, modularità dinamica e altri potenti strumenti.


Da about.com :

Una lingua interpretata viene elaborata in fase di runtime. Ogni riga viene letta, analizzata ed eseguita. Il dover rielaborare una linea ogni volta in un ciclo è ciò che rende le lingue interpretate così lente. Questo overhead significa che il codice interpretato viene eseguito da 5 a 10 volte più lento del codice compilato. I linguaggi interpretati come Basic o JavaScript sono i più lenti. Il loro vantaggio non ha bisogno di essere ricompilato dopo le modifiche e questo è utile quando stai imparando a programmare.

Il 5-10 volte più lento non è necessariamente vero per le lingue come Java e C #, tuttavia. Sono interpretati, ma i compilatori just-in-time possono generare istruzioni di linguaggio macchina per alcune operazioni, accelerando notevolmente le cose (quasi alla velocità di un linguaggio compilato a volte).


In aggiunta alle altre risposte c'è l'ottimizzazione: quando si compila un programma, di solito non ci si preoccupa di quanto tempo ci vuole per compilare - il compilatore ha molto tempo per ottimizzare il codice. Quando si interpreta il codice, è necessario farlo molto rapidamente, quindi alcune delle ottimizzazioni più intelligenti potrebbero non essere possibili.


Le lingue interpretate devono leggere e interpretare il codice sorgente al momento dell'esecuzione. Con il codice compilato gran parte di questa interpretazione viene eseguita in anticipo (al momento della compilazione).


Loop a 100 volte, i contenuti del loop sono interpretati 100 volte in codice di basso livello.

Non memorizzato nella cache, non riutilizzato, non ottimizzato.

In termini semplici, un compilatore interpreta una volta in codice di basso livello

Modifica, dopo i commenti:

  • JIT è un codice compilato , non interpretato. È compilato in un secondo momento, non in anticipo
  • Mi riferisco alla definizione classica, non alle moderne implementazioni pratiche

Non esiste una lingua interpretata. Qualsiasi linguaggio può essere implementato da un interprete o un compilatore. In questi giorni la maggior parte delle lingue ha implementazioni usando un compilatore.

Detto questo, gli interpreti di solito sono più lenti, perché hanno bisogno di elaborare il linguaggio o qualcosa di abbastanza vicino ad esso in fase di esecuzione e di tradurlo in istruzioni macchina. Un compilatore esegue questa traduzione sulle istruzioni della macchina solo una volta, dopo di che vengono eseguite direttamente.


Pochissimi linguaggi di scripting contemporanei sono "interpretati" in questi giorni; in genere vengono compilati al volo, sia in codice macchina o in un linguaggio bytecode intermedio, che è (più efficiente) eseguito in una macchina virtuale.

Detto questo, sono più lenti perché la tua cpu sta eseguendo molte più istruzioni per "linea di codice", dal momento che molte delle istruzioni sono dedicate alla comprensione del codice piuttosto che fare qualsiasi cosa suggerisca la semantica della linea!


Questa è una buona domanda, ma a mio parere dovrebbe essere formulata in modo un po 'diverso, ad esempio: "Perché le lingue interpretate sono più lente delle lingue compilate?"

Penso che sia un malinteso comune che le lingue interpretate siano di per sé lente. Le lingue interpretate non sono lente , ma, a seconda del caso d'uso, potrebbero essere più lente della versione compilata. Nella maggior parte dei casi le lingue interpretate sono abbastanza veloci !

"Abbastanza veloce", più l'aumento della produttività dall'uso di un linguaggio come Python over, ad esempio, C dovrebbe essere una giustificazione sufficiente per considerare un linguaggio interpretato. Inoltre, puoi sempre sostituire alcune parti del tuo programma interpretato con un'implementazione C rapida, se hai davvero bisogno di velocità. Ma poi di nuovo, misurare prima e determinare se la velocità è davvero il problema, quindi ottimizzare.


Tutte le risposte sembrano mancare il vero punto importante qui. È il dettaglio di come viene implementato il codice "interpretato".

I linguaggi di script interpretati sono più lenti perché il loro metodo, oggetto e modello di spazio variabile globale è dinamico. Secondo me questa è la vera definizione del linguaggio degli script e non il fatto che sia interpretato. Ciò richiede molte ricerche extra sulla tabella hash per ogni accesso a una chiamata di variabile o metodo. Ed è la ragione principale per cui sono tutti terribili nel multithreading e utilizzano un GIL (Global Interpreter Lock). Questa ricerca è dove la maggior parte del tempo è speso. Si tratta di una dolorosa ricerca casuale della memoria, che fa davvero male quando si verifica un errore di cache L1 / L2.

Il Javascript Core8 di Google è così veloce e utilizza quasi la velocità C per una semplice ottimizzazione: prende il modello dei dati dell'oggetto come fisso e crea un codice interno per accedervi come la struttura dei dati di un programma compilato nativo. Quando una nuova variabile o metodo viene aggiunto o rimosso, l'intero codice compilato viene scartato e ricompilato.

La tecnica è ben spiegata nel documento di Deutsch / Schiffman "Efficient Implementation of the Smalltalk-80 System".

La domanda per cui php, python e ruby ​​non stanno facendo questo è abbastanza semplice rispondere: la tecnica è estremamente complicata da implementare.

E solo Google ha i soldi per pagare JavaScript perché un veloce interprete JavaScript basato su browser è il loro bisogno fondamentale del loro modello di business da miliardi di dollari.


Una domanda semplice, senza una vera risposta semplice. La linea di fondo è che tutti i computer "capiscono" veramente sono istruzioni binarie, che sono le lingue "veloci" come C in cui sono compilati.

Poi ci sono macchine virtuali, che comprendono diverse istruzioni binarie (come Java e .NET), ma quelle devono essere tradotte al volo su istruzioni macchina da un Just-In-Compiler (JIT). È quasi altrettanto veloce (anche più veloce in alcuni casi specifici perché la JIT ha più informazioni di un compilatore statico su come viene usato il codice).

Poi ci sono linguaggi interpretati, che di solito hanno anche le loro istruzioni binarie intermedie, ma l'interprete funziona in modo molto simile a un ciclo con una grande istruzione switch in esso con una custodia per ogni istruzione e su come eseguirla. Questo livello di astrazione sul codice macchina sottostante è lento. Ci sono più istruzioni coinvolte, lunghe catene di chiamate di funzione nell'interprete per fare anche cose semplici, e si può sostenere che la memoria e la cache non vengono utilizzate in modo efficace come risultato.

Ma le lingue interpretate sono spesso abbastanza veloci per gli scopi per cui vengono utilizzate. Le applicazioni Web sono invariabilmente legate dall'IO (solitamente l'accesso al database) che è un ordine di grandezza più lento di qualsiasi interprete.





interpreted-language