Quanto sono utili le funzioni in fase di compilazione?

5

Quanto sono utili le funzioni del tempo di compilazione? Personalmente non ho lavorato in nessuna lingua che li supporti, ma in alcuni casi mi sembrano eleganti.

Per coloro che non sanno cosa intendo, una funzione di compilazione viene valutata alla compilazione piuttosto che al runtime,

quindi se hai per esempio nel tuo codice

int i =   Pow(4,34);

potresti invece fare qualcosa di simile

int i =   Pow<compilation>(4,34);

e il codice effettivo di runtime sarebbe

 int i =   295147905179352825856;

Naturalmente ci sono alcune restrizioni su quali funzioni potrebbero essere eseguite in fase di compilazione, devono essere praticamente pure / statiche, ma posso anche vedere alcune istanze in cui potrebbe essere usato per recuperare i dati in qualcosa da un file o database ( anche se nella maggior parte dei casi queste cose non dovrebbero essere compilate nel codice)

Che ne pensi, una funzionalità del genere è effettivamente utile o semplicemente "interessante"? :)

    
posta Homde 11.04.2011 - 11:32
fonte

8 risposte

7

Mi aspetto che la maggior parte dei compilatori facciano comunque questa ottimizzazione, certamente in modalità di rilascio.

Lasciare che il compilatore lo faccia è una caratteristica utile per migliorare le prestazioni, non sono sicuro che che richiede allo sviluppatore di contrassegnare il metodo in questo modo sia utile, i compilatori sono più bravi degli umani: -).

EDIT Leggere i commenti qui sotto mi ha fatto riflettere un po 'di più e realizzare un paio di cose ... Non sono un esperto di compilatori e forse la mia ipotesi era un po' ottimista. Posso vedere come sarebbe davvero difficile per un compilatore ottimizzare automaticamente qualsiasi funzione non banale.

    
risposta data 11.04.2011 - 12:13
fonte
5

Supponiamo che tu stia lavorando su un'applicazione che ha un ciclo che richiede molto tempo perché sono stati ripetuti alcuni calcoli.

La valutazione in fase di compilazione di ciò che è possibile in questo ciclo può ridurre drasticamente i tempi di esecuzione. Poiché i valori "statici" vengono calcolati in fase di compilazione, non vengono calcolati in fase di esecuzione e solo i valori che non è possibile indovinare in fase di compilazione vengono calcolati in fase di esecuzione.

Tutto ciò che può essere fatto prima della compilazione evita di doverlo fare in fase di runtime, quindi ti fa risparmiare tempo e memoria in fase di esecuzione. È fondamentalmente una potente funzione di ottimizzazione implicita.

L'altro vantaggio è che, come nel tuo esempio, puoi ancora dare un nome (funzioni o tipi) a valori che sarebbero difficili da capire se venissero scritti direttamente dove sono stati utilizzati. Quello che segue il principio ASCIUTTA e facilita la lettura.

A proposito, in C ++ sfruttiamo la generazione del codice in fase di compilazione con templates . Quando creiamo un vettore di oggetto e usiamo le sue funzioni, il codice generato sarà:

  1. il codice minimo necessario per fare ciò che devi fare con il vettore;
  2. ottimizzato in fase di compilazione perché il compilatore conoscerà molto il tipo generato, nel contesto stregone utilizzato, ecc. Aiuterà sulle prestazioni e continuerà a utilizzare il controllo dei tipi per assicurarsi che il codice generato sia "logico" - evitando molti errori di run-time che non sono semplici da eseguire il debug.
risposta data 11.04.2011 - 11:47
fonte
3

I moderni compilatori possono valutare cose statiche come quelle in fase di compilazione. Ad esempio, x = 1 + 1 viene ottimizzato dal compilatore in modo che le istruzioni della cpu prodotte siano solo x = 2 .

Una macro #define in C / C ++ che utilizza solo dati statici mi sembra una funzione di compilazione del tempo. Oppure utilizzare la parola chiave inline su una funzione spesso si traduce anche in questo.

E, sì, sono utili per motivi di prestazioni.

    
risposta data 11.04.2011 - 12:22
fonte
2

La definirei una tecnica di ottimizzazione e hai ragione che può essere applicata solo alle sole funzioni. Generalmente, un'applicazione di funzione

f a1 ... an

può essere sostituito dal suo risultato al momento della compilazione, se f è puro e i ai sono espressioni costanti. Nota che l'applicazione della funzione è di per sé un'espressione costante.

    
risposta data 11.04.2011 - 11:52
fonte
2

C'è un interessante trade-off qui coinvolto che solleverò e poi lascerò aperto per la tua edificazione.

Le funzioni di compilazione tempo richiedono che ogni build impieghi più tempo e l'esecuzione del prodotto diventa più veloce. La valutazione run-time è ottima quando i tempi dei programmatori sono costosi e il tempo dei tuoi utenti è economico. Compile-time funziona meglio quando è il contrario.

    
risposta data 11.04.2011 - 15:45
fonte
2

Quando combini le funzioni di compilazione del tempo con string mixins nel linguaggio di programmazione D, sono piuttosto utili. Ti permettono di generare codice arbitrario al momento della compilazione in modo trasparente per l'utente dell'API e lo compila come un normale codice. Questo è di enorme valore per la programmazione generativa.

    
risposta data 11.04.2011 - 16:20
fonte
1

PL / I consente di scrivere macro in PL / I stesso. Le macro sono semplicemente procedure PL / I chiamate durante la compilazione e il cui output è inserito nell'origine nel punto della chiamata.

    
risposta data 11.04.2011 - 18:59
fonte
0

Cobol ha diverse opzioni di tempo di compilazione. Ad esempio, è possibile impostare il compilatore su tutte le variabili non inizializzate su valori bassi, oppure fare in modo che il compilatore non esegua nulla e le variabili non inizializzate conterranno tutto ciò che è rimasto in memoria dall'esecuzione precedente. Ad alcuni negozi Cobol è piaciuta l'inizializzazione di basso valore, mentre altri no. Come puoi immaginare, a volte è stato uno shock culturale quando un programmatore Cobol si spostava da un negozio all'altro.

Ecco un elenco delle opzioni del compilatore Cobol per i mainframe IBM.

    
risposta data 11.04.2011 - 14:16
fonte

Leggi altre domande sui tag