【问题标题】:Why is it faster to call external scala compiler than use the runtime interpreter library?为什么调用外部 scala 编译器比使用运行时解释器库更快?
【发布时间】:2013-06-30 04:09:48
【问题描述】:

为什么调用外部 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 ")

另一方面,当像在 shell 会话中一样从命令行运行 Scala 编译器时:

scala HelloWorld.scala

打印一个 Hello World 需要 不到 0.5 秒

我正在尝试在运行时解析+执行字符串中给出的一些 Java、Scala 或类似代码(它是一个脚本解释器,即它只会在我的应用程序执行期间运行一次)。 Scala 代码显然会更好,但前提是它可以与 Java 选项一样快。 有没有比 nsc.interpreter 和外部编译器更快的替代方法在运行时从字符串执行代码? 我能找到的最好的是 Janino。它比 Scala 编译器更快,并且不需要 JDK(一个非常有趣的特性)。

作为最后一个资源,Java Scripting Engines 与反射或字节码编译的 Java 代码相比有多快?我发现,至少,它们可以编译:Compiling oft-used scripts



选择的解决方案: runtimecompilescala.

【问题讨论】:

  • 您不能在程序的早期异步运行预热代码吗?
  • “从命令行”是什么意思?来自 REPL?很明显为什么它更快:所有需要的类都已加载。
  • @ 0__ :好主意,但我做不到。它是小脚本的解释器。整体启动越快越好。
  • @sschaef:没有 REPL,只有解释器/编译器(或其他名称,我不太清楚)。问题已编辑。
  • 也许它与你的类路径中有多少东西有关......

标签: scala reflection runtime interpreter


【解决方案1】:

还有很多未说明的内容(例如内存设置),但您是在比较苹果和橙子。

命令行脚本运行器不是 REPL 会话;相反,它使用 main 方法将您的代码包装在一个简单的对象中,然后编译并运行它。

相比之下,REPL 中的每个解释行(或可编译的东西)都包装在一个对象中(导入会话历史记录,以便您参考过去的结果)。

即使是模 REPL 启动,这也会对性能产生影响,请参阅 this issue

脚本运行器的简单 wrap-it 逻辑内置于解析器中。 Here is how 脚本运行器运行编译。或者,它看起来像this is how -e is handled.

编辑:您对问题的评论暗示您确实想要 fsc 编译服务器行为。启动 fsc 并使用the compile client

【讨论】:

  • Tnx,我重新措辞以确保问题与 REPL 无关。我是否必须使用“编译器服务器”和带有套接字等的客户端?不只是一个运行时“编译器”吗?
  • 编辑问题以反映我选择的解决方案。
  • @davips IMain 是 scala repl。你也可以使用新的反射API,mirror.mkToolBox()来解析+编译。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
  • 1970-01-01
  • 2012-02-06
  • 1970-01-01
  • 2019-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多