2009-05-20 11 views

risposta

33

Quasi nessun interprete interpreta realmente il codice direttamente, riga per riga: è semplicemente troppo inefficiente. Quasi tutti gli interpreti usano una rappresentazione intermedia che può essere eseguita facilmente. Inoltre, piccole ottimizzazioni possono essere eseguite su questo codice intermedio.

Python memorizza inoltre questo codice che ha un enorme vantaggio per la prossima volta che questo codice viene eseguito: Python non deve più analizzare il codice; l'analisi è la parte più lenta nel processo di compilazione. Pertanto, una rappresentazione di bytecode riduce sostanzialmente l'overhead di esecuzione.

+1

Anche il vecchio MS BASIC sul mio TRS-80 usava uno schema di codifica molto semplice: non appena ho digitato o modificato una riga, le parole chiave BASIC sono state compresse in byte singoli. –

+1

@DavidThornley: molti computer degli anni '80 utilizzavano un derivato di MS-basic che convertiva le parole chiave in token, ma manteneva numeri e nomi di variabili in forma testuale, dovendo quindi calcolare i loro valori o cercarli in fase di runtime. Atari BASIC ha fatto più elaborazione, costruendo una tabella di variabili e sostituendo i loro nomi con gli indici. Ha inoltre convertito numeri numerici in numeri in virgola mobile in formato BCD. Solo i letterali e i commenti stringa sono stati memorizzati come testo. Tali cose avrebbero potuto consentire ad Atari BASIC di sovraperformare gli altri, tranne che il numero di ogni riga era memorizzato come binario, ma gli obiettivi GOTO ... – supercat

+1

... erano memorizzati come BCD in virgola mobile, quindi ogni GOTO richiedeva una conversione da BCD a binario . Tuttavia, è interessante il fatto che l'autore di Atari BASIC abbia convertito il programma in una rappresentazione analizzata piuttosto che semplicemente sostituendo parole chiave con token. – supercat

7

Perché l'interpretazione direttamente dal bytecode è più veloce. Evita la necessità di fare lexing, per prima cosa.

8

Perché è possibile compilare a .pyc una volta e interpretare da esso molte volte.

Quindi se si sta eseguendo uno script molte volte si ha solo il sovraccarico di analizzare il codice sorgente una volta.

6

Ri-lessare e analizzare il codice sorgente più volte, piuttosto che farlo una sola volta (il più delle volte sul primo import), sarebbe ovviamente uno sciocco e inutile spreco di sforzi.

+0

L'esecuzione di un file ".py" comporta il re-lexing e l'analisi del codice sorgente più e più volte, giusto? Se il file è di grandi dimensioni, questo può essere un sovraccarico significativo. Non sono sicuro del motivo per cui l'importazione riceve un trattamento speciale. Gradirei davvero qualsiasi aiuto nella comprensione. – batbrat

-1

Dubito molto che la ragione sia la performance, anche se si tratta di un bell'effetto collaterale. Direi che è naturale pensare che una VM costruita attorno ad un linguaggio di assemblaggio di alto livello sia più pratica che trovare e sostituire il testo in una stringa di codice sorgente.

Edit:

Okay, chiaramente, chi ha mai messo un -1 voto sulla mio post senza lasciare un commento ragionevole per spiegare sa molto poco di macchine virtuali (run-time ambienti).

http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Erik-Meijer-and-Lars-Bak-Inside-V8-A-Javascript-Virtual-Machine/

+1

Non l'ho fatto -1, ma sarò sincero che non ho capito il tuo punto, specialmente questa parte: "sarebbe più pratico che trovare e sostituire il testo in qualche stringa del codice sorgente" –

+0

Guarda il video su canale 9, o scrivi la tua VM, o due probabilmente spiegherebbero l'intero processo in dettaglio per te. Quello che intendevo per quella citazione è che a volte è più semplice eseguire ottimizzazioni su un livello più alto di astrazione rispetto all'assemblaggio. Quando lo fai normalmente lavori con un AST (abstract syntax tree), se non ne hai uno puoi comunque eseguire le stesse ottimizzazioni ma devono spostare il codice sorgente, cioè trovare e sostituire e questo è davvero poco pratico, ambienti di esecuzione tendono ad andare con altre rappresentazioni intermedie per questo motivo (vedi codice a tre indirizzi). –

+0

Il byte-code è solo una rappresentazione più efficiente e pratica dell'AST. –

2

Anche se c'è un piccolo aspetto di efficienza ad esso (è possibile memorizzare il bytecode su disco o in memoria), la sua maggior parte di ingegneria: permette di separare l'analisi da interpretare. I parser possono spesso essere creature cattive, piene di casi limite e dover conformarsi a regole esoteriche come usare la giusta quantità di lookahead e risolvere i problemi di riduzione del turno. Al contrario, l'interpretazione è davvero semplice: è solo una grande istruzione switch che utilizza l'opcode del bytecode.

Problemi correlati