2009-10-10 9 views
6

Ich baue eine Tabellenkalkulation-ähnliche Anwendung, wo viele kleine Berechnungen in einer Baumstruktur zusammengefügt werden müssen. Diese Berechnungen sind benutzerdefiniert und ich brauche eine Möglichkeit für den Benutzer, sie zur Laufzeit einzugeben.Basieren Sie einen kleinen Ausdruck DSL auf dem DLR oder halten Sie ihn in F # von Hand gerollt?

Mein aktueller Ansatz ist es, einen kleinen "Ausdruck DSL" in F # zu schreiben, wo ich die Eingabe mit FParsec analysieren, einen Syntaxbaum basierend auf einer diskriminierten Union erstellen und dann den Ausdruck auswerten kann. Das funktioniert ziemlich gut.

Allerdings denke ich darüber nach, stattdessen die Sprache auf dem DLR zu gründen. Gibt es irgendwelche Vorteile, um diese Straße hinunter zu gehen (die Eingabe analysieren, die AST mit den Scripting.AST-Daten statt meiner eigenen generieren und die DLR die Ausführung der Berechnung übernehmen lassen)?

Jede Berechnung wird wahrscheinlich ziemlich klein sein. Die Abhängigkeit zwischen den Berechnungen wird auf einer höheren Ebene berücksichtigt.

Kann ich eine bessere Leistung erwarten, da der DLR CIL-Code für den Ausdruck generiert oder wird der Overhead dies auffressen?

(wie für eine vorhandene Sprache wie Ironpython verwendet, wird es wahrscheinlich schwierig sein, da ich plane eine Menge Slice-and-Dice-Operatoren und Dimensionalität-Handling-Material zum Sprachsyntax hinzufügen)

Antwort

7

Es ist schwierig, eine Frage so umfassend zu beantworten, aber hier sind einige meiner Gedanken.

Die Verwendung von F # zum Aufbau des Parsers klingt gut.

FSParsec ist eine großartige Bibliothek. Ich bin ein wenig zu FSLex und FSYacc. Wie auch immer, in F # gibt es Bibliotheken, die speziell für das Parsen entwickelt wurden, was Ihnen Zeit spart.

Generieren von Code mit dem DLR klingt OK.

Der DLR ist eine großartige Plattform für die dynamische Codegenerierung. Ihre Bewerbung ist jedoch viel spezifischer. Wenn Sie sich darauf beschränken, nur Werte zu berechnen, sollten Sie die Expression Trees APIs von .NET 3.5 verwenden. Diese API dient zur Darstellung von beliebigen Code-Ausdrücken. Der DLR hingegen ist als Laufzeit- oder dynamische Sprache konzipiert. Ich sage nicht, dass es unmöglich ist, nur dass es nicht das richtige Werkzeug für den Job ist.

Kompilieren Sie Ihren generierten Code nicht.

Wenn Sie mit dem DLR arbeiten, um Ihren AST zu repräsentieren, werden die Kosten für das Kompilieren und Ausführen wahrscheinlich viel größer sein, als einfach den Baum zu interpretieren. Kompilieren Sie den Code, wenn: A.) Sie die gleiche Funktion/Methode mehrmals ausführen oder B.) die Funktion/Methode sehr kompliziert ist.

C# + DLR, IronPython, F #, oder eine Kombination der drei sind alle Sound-Optionen. Letztendlich ist die "richtige" Wahl derjenige, der die Aufgabe so schnell wie möglich erledigt.

+1

Vielen Dank für Ihre Einblicke. Ich habe die Linq Expression Bäume komplett übersehen. Ich werde versuchen, meinen Parser zu modifizieren, um mit dieser API Bäume zu generieren und einige Leistungstests für ihre Bewertung durchzuführen, um sie mit der naiven Interpretation/Bewertung zu vergleichen, die ich jetzt in F # mache. – Rickard

+1

Beachten Sie, dass Sie F # -Angaben verwenden können, und in der FSharp.PowerPack.Linq-Bibliothek können Sie den F # -Anführungsausdruck in einen LINQ-Ausdrucksbaum konvertieren.Es gibt nicht eine Menge Dokumentation zu diesem Thema, aber Sie könnten interessiert sein. –