6

ランタイム インタープリター ライブラリを使用するよりも、外部の scala コンパイラを呼び出す方が速いのはなぜですか? 以下のコードでは、インタープリターをウォームアップするのにほぼ 2 秒かかります。

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 ")

一方、シェル セッションのようにコマンド ラインから Scala コンパイラを実行する場合は、次のようになります。

scala HelloWorld.scala

Hello World を出力するのに0.5 秒もかかりません。

実行時に文字列で指定されたJava、Scala、または同様のコードを解析+実行しようとしています(これはスクリプトインタープリターです。つまり、アプリの実行中に1回だけ実行されます)。Scala コードの方が明らかに優れていますが、Java オプションと同じくらい高速である場合に限られます。 実行時に文字列からコードを実行するために、nsc.interpreter と外部コンパイラよりも高速な代替手段はありますか? 私が見つけた最高のものはJaninoでした。Scala コンパイラよりも高速で、JDK を必要としません (非常に興味深い機能です)。

最後のリソースとして、リフレクションまたはバイトコードでコンパイルされた Java コードと比較して、Java Scripting Engineはどのくらい高速ですか? 少なくとも、それらはコンパイルできることがわかりました:頻繁に使用されるスクリプトのコンパイル



選択したソリューション: runtimecompilescala

4

1 に答える 1

1

記載されていないことがたくさんありますが (メモリ設定など)、リンゴとオレンジを比較しています。

コマンドライン スクリプト ランナーは REPL セッションではありません。代わりに、メイン メソッドを使用してコードを単純なオブジェクトにラップし、それをコンパイルして実行します。

対照的に、REPL 内の解釈された各行 (またはコンパイル可能なもの) はオブジェクトにラップされます (過去の結果を参照できるようにセッション履歴がインポートされます)。

modulo REPL 起動であっても、これはパフォーマンスに影響を与えます。この問題を参照してください。

スクリプト ランナーの単純なラップイット ロジックがパーサーに組み込まれています。 スクリプト ランナーがコンパイルを実行する方法を次に示します。または、これは -e の処理方法のようです。

編集:質問に対するコメントは、 fsc compile サーバーの動作が本当に必要であることを意味します。fsc を起動し、コンパイル クライアントを使用します。

于 2013-07-01T04:39:22.787 に答える