Java 编译速度与 Scala 编译速度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3490383/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java compile speed vs Scala compile speed
提问by user405163
I've been programming in Scala for a while and I like it but one thing I'm annoyed by is the time it takes to compile programs. It's seems like a small thing but with Java I could make small changes to my program, click the run button in netbeans, and BOOM, it's running, and over time compiling in scala seems to consume a lot of time. I hear that with many large projects a scripting language becomes very important because of the time compiling takes, a need that I didn't see arising when I was using Java.
我已经在 Scala 中编程了一段时间,我喜欢它,但让我烦恼的一件事是编译程序所需的时间。这似乎是一件小事,但是使用 Java 我可以对我的程序进行一些小的更改,单击 netbeans 中的运行按钮,然后 BOOM,它正在运行,随着时间的推移,在 Scala 中编译似乎会消耗很多时间。我听说在许多大型项目中,脚本语言变得非常重要,因为编译需要时间,而我在使用 Java 时并没有看到这种需求。
But I'm coming from Java which as I understand it, is faster than any other compiled language, and is fast because of the reasons I switched to Scala(It's a very simple language).
但是我来自 Java,据我所知,它比任何其他编译语言都快,并且由于我切换到 Scala(这是一种非常简单的语言)的原因,速度很快。
So I wanted to ask, can I make Scala compile faster and will scalac ever be as fast as javac.
所以我想问一下,我能不能让 Scala 编译得更快,并且 scalac 会和 javac 一样快。
采纳答案by Aaron Novstrup
The Scala compiler is more sophisticated than Java's, providing type inference, implicit conversion, and a much more powerful type system. These features don't come for free, so I wouldn't expect scalac to ever be as fast as javac. This reflects a trade-off between the programmer doing the work and the compiler doing the work.
Scala 编译器比 Java 更复杂,提供类型推断、隐式转换和更强大的类型系统。这些功能不是免费提供的,所以我不希望 scalac 像 javac 一样快。这反映了执行工作的程序员和执行工作的编译器之间的权衡。
That said, compile times have already improved noticeably going from Scala 2.7 to Scala 2.8, and I expect the improvements to continue now that the dust has settled on 2.8. This pagedocuments some of the ongoing efforts and ideas to improve the performance of the Scala compiler.
也就是说,从 Scala 2.7 到 Scala 2.8 的编译时间已经有了明显的改善,我希望随着 2.8 的尘埃落定,这些改进会继续下去。本页记录了一些正在进行的改进 Scala 编译器性能的努力和想法。
回答by Denis Tulskiy
Use fsc- it is a fast scala compiler that sits as a background task and does not need loading all the time. It can reuse previous compiler instance.
使用fsc- 它是一个快速的 Scala 编译器,作为后台任务,不需要一直加载。它可以重用以前的编译器实例。
I'm not sure if Netbeans scala plugin supports fsc (documentation says so), but I couldn't make it work. Try nightly builds of the plugin.
我不确定 Netbeans scala 插件是否支持 fsc(文档是这样说的),但我无法让它工作。尝试每晚构建插件。
回答by VonC
The latest revisions of Scala-IDE(Eclipse) are much better atmanaging incremental compilation.
Scala-IDE(Eclipse)的最新版本在管理增量编译方面要好得多。
See "What's the best Scala build system?" for more.
有关更多信息,请参阅“最好的 Scala 构建系统是什么?”。
The other solution is to integrate fsc - Fast offline compiler for the Scala 2 language- (as illustrated in this blog post) as a builder in your IDE.
另一种解决方案是将fsc(用于 Scala 2 语言的快速离线编译器)(如本博客文章中所示)集成为 IDE 中的构建器。
But not in directlyEclipse though, as Daniel Spiewakmentions in the comments:
但不是直接在Eclipse 中,正如Daniel Spiewak在评论中提到的:
You shouldn't be using FSC within Eclipse directly, if only because Eclipse is already using FSC under the surface.
FSC is basically a thin layer on top of the resident compiler which is precisely the mechanism used by Eclipse to compile Scala projects.
您不应该直接在 Eclipse 中使用 FSC,因为 Eclipse 已经在表面下使用 FSC。
FSC 基本上是驻留编译器之上的一个薄层,这正是 Eclipse 用于编译 Scala 项目的机制。
Finally, as Hymanson Davisreminds me in the comments:
最后,正如Hyman逊戴维斯在评论中提醒我的那样:
sbt (Simple build Tool)also include some kind of "incremental" compilation (through triggered execution), even though it is not perfect, and enhanced incremental compilation is in the work for the upcoming 0.9 sbt version.
sbt(简单构建工具)还包括某种“增量”编译(通过触发执行),尽管它并不完美,并且正在为即将到来的 0.9 sbt 版本提供增强的增量编译。
回答by Randall Schulz
I'm sure this will be down-voted, but extremely rapid turn-around is not always conducive to quality or productivity.
我相信这会被否决,但极快的周转并不总是有利于质量或生产力。
Take time to think more carefully and execute fewer development micro-cycles. Good Scala code is denser and more essential (i.e., free from incidental details and complexity). It demands more thought and that takes time (at least at first). You can progress well with fewer code / test / debug cycles that are individually a little longer and still improve your productivity and the quality of your work.
花时间更仔细地思考并执行更少的开发微周期。好的 Scala 代码更密集、更重要(即,没有附带的细节和复杂性)。它需要更多的思考,而这需要时间(至少一开始是这样)。您可以通过更少的代码/测试/调试周期取得良好进展,这些周期单独更长一些,并且仍然可以提高您的生产力和工作质量。
In short: Seek an optimum working pattern better suited to Scala.
简而言之:寻求更适合 Scala 的最佳工作模式。
回答by oxbow_lakes
You should be aware that Scala compilation takes at least an order of magnitude longer than Java to compile. The reasons for this are as follows:
您应该知道 Scala 编译所需的时间至少比 Java 长一个数量级。原因如下:
- Naming conventions (a file
XY.scala
file need not contain a class calledXY
and may contain multiple top-level classes). The compiler may therefore have to search more source files to find a given class/trait/object identifier. - Implicits - heavy use of implicits means the compiler needs to search any in-scope implicit conversion for a given method and rank them to find the "right" one. (i.e. the compiler has a massively-increased search domain when locating a method.)
- The type system - the scala type system is way more complicated than Java's and hence takes more CPU time.
- Type inference - type inference is computationally expensive and a job that
javac
does not need to do at all scalac
includes an 8-bit simulator of a fully armed and operational battle station, viewable using the magic key combination CTRL-ALT-F12 during the GenICodecompilation phase.
- 命名约定(文件
XY.scala
文件不需要包含被调用的类XY
并且可以包含多个顶级类)。因此,编译器可能必须搜索更多的源文件才能找到给定的类/特征/对象标识符。 - 隐式 - 大量使用隐式意味着编译器需要搜索给定方法的任何范围内的隐式转换,并对它们进行排名以找到“正确”的方法。(即编译器在定位方法时具有大量增加的搜索域。)
- 类型系统 - scala 类型系统比 Java 复杂得多,因此需要更多的 CPU 时间。
- 类型推断 - 类型推断在计算上是昂贵的,而且是一项
javac
根本不需要做的工作 scalac
包括一个全武装和可操作的战斗站的 8 位模拟器,在GenICode编译阶段使用魔术组合键 CTRL-ALT-F12 可以查看。
回答by Randall Schulz
The best way to do Scala is with IDEA and SBT. Set up an elementary SBT project (which it'll do for you, if you like) and run it in automatic compile mode (command ~compile
) and when you save your project, SBT will recompile it.
使用 Scala 的最佳方法是使用 IDEA 和 SBT。设置一个基本的 SBT 项目(如果你愿意,它会为你做)并在自动编译模式(命令~compile
)下运行它,当你保存你的项目时,SBT 将重新编译它。
You can also use the SBT plug-in for IDEA and attach an SBT action to each of your Run Configurations. The SBT plug-in also gives you an interactive SBT console within IDEA.
您还可以使用 IDEA 的 SBT 插件并将 SBT 操作附加到您的每个运行配置。SBT 插件还为您提供了 IDEA 中的交互式 SBT 控制台。
Either way (SBT running externally or SBT plug-in), SBT stays running and thus all the classes used in building your project get "warmed up" and JIT-ed and the start-up overhead is eliminated. Additionally, SBT compiles only source files that need it. It is by far the most efficient way to build Scala programs.
无论哪种方式(外部运行的 SBT 或 SBT 插件),SBT 都会保持运行,因此用于构建项目的所有类都得到“预热”和 JIT,并消除了启动开销。此外,SBT 只编译需要它的源文件。这是迄今为止构建 Scala 程序最有效的方法。
回答by Martin Odersky
There are two aspects to the (lack of) speed for the Scala compiler.
Scala 编译器的(缺乏)速度有两个方面。
Greater startup overhead
Scalac itself consists of a LOT of classes which have to be loaded and jit-compiled
Scalac has to search the classpath for all root packages and files. Depending on the size of your classpath this can take one to three extra seconds.
Overall, expect a startup overhead of scalac of 4-8 seconds, longer if you run it the first time so disk-caches are not filled.
Scala's answer to startup overhead is to either use fsc or to do continuous building with sbt. IntelliJ needs to be configured to use either option, otherwise its overhead even for small files is unreasonably large.
Slower compilation speed. Scalac manages about 500 up to 1000 lines/sec. Javac manages about 10 times that. There are several reasons for this.
Type inference is costly, in particular if it involves implicit search.
Scalac has to do type checking twice; once according to Scala's rules and a second time after erasure according to Java's rules.
Besides type checking there are about 15 transformation steps to go from Scala to Java, which all take time.
Scala typically generates many more classes per given file size than Java, in particular if functional idioms are heavily used. Bytecode generation and class writing takes time.
On the other hand, a 1000 line Scala program might correspond to a 2-3K line Java program, so some of the slower speed when counted in lines per second has to balanced against more functionality per line.
We are working on speed improvements (for instance by generating class files in parallel), but one cannot expect miracles on this front. Scalac will never be as fast as javac. I believe the solution will lie in compile servers like fsc in conjunction with good dependency analysis so that only the minimal set of files has to be recompiled. We are working on that, too.
更大的启动开销
Scalac 本身包含许多必须加载和 jit 编译的类
Scalac 必须在类路径中搜索所有根包和文件。根据您的类路径的大小,这可能需要一到三秒钟的额外时间。
总体而言,预计 scalac 的启动开销为 4-8 秒,如果您第一次运行它,则时间会更长,因此磁盘缓存不会被填满。
Scala 对启动开销的回答是使用 fsc 或使用 sbt 进行连续构建。IntelliJ 需要配置为使用任一选项,否则即使对于小文件,其开销也会大得不合理。
编译速度较慢。Scalac 管理大约 500 到 1000 行/秒。Javac 管理着大约 10 倍。有几个原因。
类型推断的成本很高,尤其是当它涉及隐式搜索时。
Scalac 必须做两次类型检查;根据 Scala 的规则进行一次,根据 Java 的规则在擦除后进行第二次。
除了类型检查之外,从 Scala 到 Java 大约需要 15 个转换步骤,这些都需要时间。
Scala 通常为每个给定的文件大小生成比 Java 多得多的类,尤其是在大量使用函数式惯用语的情况下。字节码生成和类编写需要时间。
另一方面,一个 1000 行的 Scala 程序可能对应一个 2-3K 行的 Java 程序,所以以每秒行数计算时,一些较慢的速度必须与每行更多的功能相平衡。
我们正在努力提高速度(例如通过并行生成类文件),但在这方面不能指望奇迹。Scalac 永远不会像 javac 那样快。我相信解决方案将在于像 fsc 这样的编译服务器结合良好的依赖关系分析,以便只需要重新编译最少的文件集。我们也在为此努力。
回答by OlliP
You can use the JRebel plugin which is free for Scala. So you can kind of "develop in the debugger" and JRebel would always reload the changed class on the spot.
您可以使用 Scala 免费的 JRebel 插件。所以你可以“在调试器中开发”,JRebel 总是会在现场重新加载更改的类。
I read some statement somewhere by Martin Odersky himself where he is saying that the searches for implicits (the compiler must make sure there is not more than one single implicit for the same conversion to rule out ambiguities) can keep the compiler busy. So it might be a good idea to handle implicits with care.
我在某处读到 Martin Odersky 本人的一些声明,他说搜索隐式(编译器必须确保同一转换不超过一个隐式以排除歧义)可以使编译器忙碌。因此,小心处理隐式可能是个好主意。
If it doesn't have to be 100% Scala, but also something similar, you might give Kotlina try.
如果它不必是 100% Scala,但也必须是类似的东西,你可以试试Kotlin。
-- Oliver
——奥利弗