2013-09-04 7 views
9

Esistono linguaggi interpretati, come Lisp, Tcl, Perl, ecc., Che rendono facile la definizione di lambda/proc/sub all'interno del codice durante il runtime e per valutare all'interno della stessa sessione.Assemblare una funzione secondo necessità e calcolarla velocemente

Ci sono linguaggi compilati, come C++, che dovrebbero essere eseguiti molto più velocemente di quelli interpretati, ma che definiscono una funzione all'interno di un programma compilato durante il runtime e l'esecuzione non è facile, se possibile.

Il problema è quello di effettuare le seguenti operazioni:

  1. definire una funzione durante il runtime: per esempio, sulla base dei dati di input iniziali derivare un modello analitico dei dati.

  2. Esegui rapidamente la funzione sopra descritta in un ciclo: ad esempio, applica il modello analitico derivato per analizzare i dati in entrata.

Una soluzione che ho visto non era molto carina:

  1. Una procedura che rappresenta il modello analitico è derivata incorporato Tcl sulla base dei dati di input iniziali.

  2. Una tabella di ricerca è stata creata valutando la procedura in Tcl su una matrice di punti campione che, in termini ottimistici, coprirebbero l'intervallo di applicabilità.

  3. La tabella di ricerca è stata passata dall'interprete Tcl al binario (che è stato sviluppato in C++).

  4. Quindi i dati in arrivo sono stati analizzati interpolando tra valori "abbastanza vicini" nella tabella di ricerca.

La soluzione di cui sopra funziona, ma presenta alcuni problemi, sia concettuali che computazionali. Quindi la domanda: è possibile definire una funzione puramente in C++ e renderla disponibile per l'esecuzione all'interno della stessa sessione di runtime?

Concettualmente, è possibile fare qualcosa come creare una funzione come stringa, compilarla in memoria e in qualche modo collegarla nuovamente al file binario che viene eseguito?

+0

Ci sono molti compilatori Lisp efficienti là fuori. Ci sono macchine virtuali compilate con JIT come .NET e JVM. Ci sono compilatori C incorporabili (tcc, clang). È anche abbastanza semplice generare LLVM IR direttamente, con tutti i vantaggi di un potente compilatore di ottimizzazione. –

+1

E anche gli interpreti C++ sono ampiamente utilizzati, vedere CINT e ROOT. –

risposta

12

Se vuoi qualcosa che funziona subito, dai uno sguardo a ExprTK. Se vuoi scrivere un parser di espressioni, controlla Boost Spirit.

Un'alternativa sarebbe quella di creare codice C++ al volo, compilarlo come libreria condivisa (plugin) e caricarlo in fase di runtime. Questa probabilmente sarebbe la soluzione più veloce.

+0

Grazie, al primo sguardo Boost Spirit sembra promettente. Sai quanto è veloce? Genera codice binario ottimizzato che può essere eseguito in un loop sufficientemente veloce? – Michael

+0

Un parser scritto con Spirit creerebbe tipicamente un Abstract Syntax Tree (AST), che è semplicemente un'aggregazione di operazioni e valori. Ecco un esempio: [Boost Spirit AST example] (http: //www.boost.org/doc/libs/1_41_0/libs/spirito/example./qi/calc2_ast.cpp). Quindi il risultato sarà generalmente più lento del codice compilato ottimizzato. Se la velocità è la tua principale preoccupazione, dovresti dare l'ultimo suggerimento. – ToniBig

+13

@Michael Boost.Spirit va bene per l'analisi, ma la valutazione dell'AST sarà il grande killer in termini di prestazioni. Anche sviluppare con Boost.Spirit richiede molta pazienza e la maggior parte dei compilatori riesce a malapena a far fronte a qualcosa di più complesso di una semplice grammatica in stile calcolatrice +/-/* - i tempi di compilazione sono incredibilmente lunghi e tutti i tipi di trucchi devono essere fatti come rompere le grammatiche in più file, ecc. –