2013-06-30 4 views
5

Warum ist es schneller, externen Scala-Compiler aufzurufen, als die Laufzeit-Interpreter-Bibliothek zu verwenden? Im Code unter dauert es fast 2s, um den Interpreter aufzuwärmen.Warum ist es schneller, einen externen Scala-Compiler aufzurufen, als die Laufzeit-Interpreter-Bibliothek zu verwenden?

val out = new PrintStream(new FileOutputStream("/dev/null")) 
val flusher = new java.io.PrintWriter(out) 
val interpret = { 
    val settings = new scala.tools.nsc.GenericRunnerSettings(println _) 
    settings.usejavacp.value = true 
    new scala.tools.nsc.interpreter.IMain(settings, flusher) 
} 
interpret.interpret(" ") // <-- warming up 
interpret.interpret(" Hello World ") 

In der anderen Hand, wenn wie in einer Shell-Sitzung Compiler von der Kommandozeile Scala ausgeführt wird:

scala HelloWorld.scala 

es weniger als 0,5 s nimmt eine Hallo Welt zu drucken.

Ich versuche, einige Java, Scala oder ähnlichen Code in einer Zeichenfolge während der Laufzeit zu analysieren + auszuführen (es ist ein Skript-Interpreter, d. H. Es wird nur einmal während meiner App-Ausführung ausgeführt). Scala-Code wäre natürlich besser, aber nur, wenn es so schnell wie die Java-Option sein kann. Gibt es eine schnellere Alternative als nsc.interpreter und externen Compiler zum Ausführen von Code aus einer Zeichenfolge zur Laufzeit? Das beste, was ich finden konnte, war Janino; Es ist schneller als der Scala-Compiler und benötigt kein JDK (ein sehr interessantes Feature).

Als letzte Ressource, wie schnell sind Java Scripting Engines im Vergleich zu einem reflektierten oder bytecode-kompilierten Java-Code? Ich habe herausgefunden, dass sie zumindest kompiliert werden können: Compiling oft-used scripts.



Gewählte Lösung: runtimecompilescala.

+1

Können Sie den Aufwärmcode nicht zu einem früheren Zeitpunkt in Ihrem Programm asynchron ausführen? –

+1

Was meinst du mit "von der Befehlszeile"? Von der REPL? Da ist klar, warum es schneller ist: Alle benötigten Klassen sind bereits geladen. – sschaef

+0

@ 0__: Gute Idee, aber ich kann nicht. Es ist ein Interpreter von kleinen Skripten. Je schneller der Start, desto besser. –

Antwort

1

Es gibt viele Dinge, die nicht angegeben sind (wie Speichereinstellungen), aber Sie vergleichen Äpfel und Orangen.

Der Befehlszeilenskript-Runner ist keine REPL-Sitzung. Stattdessen wird der Code in ein einfaches Objekt mit einer Hauptmethode eingeschlossen, kompiliert und ausgeführt.

Im Gegensatz dazu wird jede interpretierte Zeile (oder kompilierbare Sache) in der REPL in ein Objekt eingeschlossen (wobei der Sitzungsverlauf importiert wird, so dass Sie auf frühere Ergebnisse verweisen können).

Sogar Modulo REPL Start-up, dies hat Auswirkungen auf die Leistung, siehe this issue.

Die einfache Wrap-It-Logik für den Skript-Runner ist in den Parser integriert. Here is how Der Skript-Runner führt die Kompilierung aus. Oder es sieht aus wie this is how -e is handled.

Edit: Ihr Kommentar zu Ihrer Frage impliziert, dass Sie wirklich wollen, fsc Serververhalten kompilieren. Feuer fsc und verwenden the compile client.

+0

Tnx, ich formulierte, um sicherzustellen, dass die Frage nicht über REPL ist. Muss ich "Compiler Server" und Client mit Sockets etc. Es gibt nicht nur einen Laufzeit "Compiler"? –

+0

Bearbeitete Frage, um meine gewählte Lösung widerzuspiegeln. –

+0

@davips IMain ist die scala repl. Sie können auch die neue Reflection-API, mirror.mkToolBox() zum Parsen und Kompilieren verwenden. –

Verwandte Themen