prof. Nunzio Brugaletta |
LinPROG |
In passato lo schema predominante per la traduzione e l'esecuzione di un programma era lo schema compilativo. Tutti i linguaggi di programmazione adottavano tale schema:
il programma viene compilato su una determinata piattaforma (risorse hardware, principalmente la CPU, e sistema operativo).
L'eseguibile risulta velocissimo perché sfrutta le caratteristiche peculiari dell'hardware.
La forza principale dello schema compilativo è anche il suo limite: la trasportabilità. Tutte le volte che si vuole adattare il programma ad un nuovo hardware o Sistema Operativo è necessario, nella migliore delle ipotesi, ricompilare il programma per la nuova piattaforma.
Per risolvere il problema delle dipendenze del programma da una piattaforma, si è adottato uno schema che, basandosi su librerie compilate per le varie piattaforme, potesse eseguire il codice senza necessità di ricompilazione. L'esecuzione del programma è più lenta e si richiedono più risorse di memoria: quelle necessarie per l'interprete e per il programma, ma non c'è necessità di ricompilare il programma che diventa portabile. La maggiore lentezza di un programma interpretato rispetto ad uno compilato è dovuta anche al fatto che, nel caso di un interprete, la CPU deve eseguire l'interprete e il programma. Si pensi, inoltre, a come verrebbe eseguita una struttura ciclica nello schema compilativo e in quello interpretativo.
Schema compilativo: il programma viene tradotto in linguaggio macchina e una istruzione presente nel corpo del ciclo può essere eseguita tutte le volte richieste e il tempo di esecuzione dipende soltanto dai cicli macchina necessari per l'esecuzione di quella istruzione.
Schema interpretativo: una istruzione presente all'interno del ciclo viene controllata e interpretata ogni volta che se ne richiede la sua esecuzione.
In conseguenza delle peculiarità dei due schemi presentati si utilizza lo schema compilativo in ambienti in cui la velocità o le dimensioni sono fattori critici e si utilizza lo schema interpretativo in fase di sviluppo di un programma quando, per la sua messa a punto, si risparmia il tempo di nuove compilazioni oppure quando la velocità non è un fattore critico e, invece, è importante la portabilità: si pensi, per esempio, alle applicazioni web.
L'utilizzo di ciascuno dei due schemi esposti comporta vantaggi e svantaggi, anche in relazione allo stato di avanzamento dello sviluppo di una applicazione:
Schema compilativo: adatto per preparare il programma all'esecuzione nell'ambiente cui è destinato. Se cambia la piattaforma, il programma deve essere ricompilato.
Schema interpretativo: adatto alla fase di sviluppo di un programma dove non è importante la velocità ma il test sull'algoritmo per la correttezza del programma. Il programma è indipendente dalla piattaforma. L'esecuzione del programma è molto più lenta dell'equivalente compilato.
Nel tempo sono stati tentati anche degli ibridi allo scopo di poter sfruttare i vantaggi dei due schemi esposti. Un tipico esempio in cui viene adottato un approccio di questo genere lo si trova per il linguaggio Java. In questo caso viene utilizzato un compilatore che produce codice in linguaggio intermedio (codice per una CPU generica) che viene chiamato bytecode. In questo modo il programma è portabile: un programma in bytecode è eseguito da un altro programma (l'interprete) che viene anche chiamato macchina virtuale. Nel caso di Java si avrà la JVM (Java Virtual Machine).
Per cercare di ridurre la differenza di prestazione fra un programma compilato e uno interpretato sono state introdotte tecniche di compilazione just-in time. In questi casi, in sede di esecuzione, il bytecode invece di essere interpretato, viene passato ad un compilatore che lo traduce in linguaggio macchina subito prima dell'esecuzione.
http://ennebi.solira.org |
ennebi@solira.org |