Come viene controllato il tipo in un interprete / compilatore di un linguaggio dinamico, come JavaScript?


11

Nei linguaggi dinamici, come JavaScript o Python, il tipo di una variabile viene determinato in fase di esecuzione. Questo è uno dei motivi per cui sono più lenti dei linguaggi digitati come Java.

Come viene eseguito il controllo del tipo? Qual è la ragione essenziale per cui questo processo è lento?


Non sono più lenti perché sono dinamici, sono più lenti perché è più difficile renderli più veloci. JavaScript è in realtà il più ottimizzato ed è abbastanza veloce.
Derek Litz,

Risposte:


5

C'è confusione nella domanda.

Si presume che il controllo del tipo sia lento, il che non è necessariamente il caso.

La domanda sembra anche confondere il processo di invio del tipo con il controllo del tipo , e sono due cose diverse. Uno è un processo che viene eseguito in fase di esecuzione, l'altro un processo in fase di compilazione. Ho il sospetto che la domanda si stia davvero ponendo sul tipo di spedizione.

È l'invio di tipi che può introdurre un sovraccarico in fase di esecuzione, poiché il calcolo impiega tempo con istruzioni che decidono, in modo dinamico, quale azione intraprendere, in base ai tipi di valori che vede in fase di esecuzione. ad es. in un linguaggio dinamico, se applico "+" su due cose, potrei significare addizione numerica o concatenazione di stringhe, quindi ho bisogno di passare il tempo a guardare ciò che è a portata di mano per decidere cosa fare. Esistono strategie di valutazione che possono ridurre il costo della spedizione dinamica. (ad es. tracciamento di JIT)

Per quanto riguarda l'esecuzione del controllo del tipo in JavaScript, consultare: http://www.cs.brown.edu/~sk/Publications/Papers/Published/gsk-flow-typing-theory/ . Per una panoramica più generale di come funzionano i correttori di tipo, un manuale di linguaggio di programmazione standard coprirà gli algoritmi. Ad esempio, http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/


Ho anche scritto un piccolo sondaggio sulla traccia di JIT e linguaggi dinamici in hashcollision.org/comprehensive/tracing.pdf

L'interprete Javascript trasporta bit di tag con ciascun valore per il tipo dispatch. Potresti approfondire un po 'su questo? Ad esempio, a che cosa servono i tag tags? Un po corrisponde a un tipo?

Il concetto di un tipo non è sempre collegato alla rappresentazione. Potremmo avere un concetto di un tipo di "miglio" rispetto a un tipo di "chilometro", ad esempio, ed è ragionevole avere un linguaggio in grado di rilevare staticamente, al momento della compilazione, se i calcoli applicano erroneamente operazioni su valori che confondono i tipi . Potresti immaginare che avrebbero la stessa rappresentazione, e se il compilatore può, al momento della compilazione, garantire che non siano mai mescolati, allora non c'è motivo per cui i valori avrebbero bisogno dell'etichetta aggiuntiva nella rappresentazione.

1
Continua: ma spesso, soprattutto nelle lingue dinamiche, si desidera rappresentare valori di diversi tipi. Esistono diversi modi per fare questa discriminazione. I tag di tipo sono comuni, ma esistono altre tecniche. Ad esempio, è possibile posizionare determinati tipi in aree di memoria bloccate. Vedere "Rappresentazione delle informazioni sul tipo in linguaggi tipizzati dinamicamente". lambda-the-ultimate.org/node/3912 per un sondaggio completo delle tecniche di rappresentazione.

7

In sostanza, nei linguaggi non tipizzati, ogni riferimento a un oggetto che contiene sia il tipo che il valore. Ad esempio, var a = 3punta a un'istanza che contiene il valore 3 e il tipo int, se lo si fa a = "bla", il riferimento viene aggiornato a un'istanza che contiene la stringa "bla" e la stringa del tipo, l'oggetto vecchio viene scartato, ecc ...

Questo è lento perché ogni volta che un'operazione (ad es. a + b) Deve essere eseguita su questo tipo di base, il runtime deve prima fare la dereferenza sugli oggetti, verificare che il loro tipo sia compatibile, eseguire l'operazione, creare un nuovo oggetto.

Al contrario, a + bin C ++ o Java verifica al momento della compilazione che i tipi siano validi e compatibili, quindi aeb vengono memorizzati come valori immediati (non riferimenti) e l'aggiunta è una semplice operazione del processore su questi valori.

Ovviamente, tutto ciò è molto teorico. In pratica, su questo processo si può fare molta ottimizzazione per evitare la maggior parte delle spese generali e le lingue tipizzate dinamicamente possono essere abbastanza veloci.


1
Trucchi come le cache in linea polimorfiche possono migliorare notevolmente le prestazioni. Gli scritti di David Ungar (Self) ed Eliot Miranda (Squeak, Visual Works Smalltalk virtual machines) sono i più istruttivi, per quanto riguarda le prestazioni del linguaggio dinamico.
Frank Shearar,

0

Ogni valore viene memorizzato insieme al suo tipo, che è necessario ispezionare per primo. Anche le conversioni dicono da una stringa all'altra tramite l'ispezione, al volo.


Sì, eccolo, è solo un controllo di runtime, niente di speciale.
anon
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.