Scala与Java相比表现如何?

16

这个问题已经包含了所有需要知道的信息。

提问背后的原因是我即将开始一个小的旁门左道项目,并希望使用 Scala 进行开发。我学习 Scala 已经有一个月了,现在我已经可以很自如地使用它来工作。Scala 编译器本身的速度相当慢(除非你使用 fsc)。那么它在 JVM 上的表现如何?我之前在 Groovy 上工作过,有时候性能比 Java 还要好。我的问题是 Scala 相对于 Java 在 JVM 上的表现如何。我知道 Scala 有一些非常好的特性(函数式编程、动态语言、静态类型等等),但最终我们需要的是性能...


2
请记住,Scala编译器需要处理的工作比Java编译器要多得多。因此,它的速度不会像你在更简单的语言中习惯的那样快,这是可以预料的。 - Randall Schulz
3个回答

25

我的大部分工作都使用Scala语言进行高性能编程。如果真的非常注重性能,那么Scala几乎总是与Java相当甚至更好。如果不小心处理例如对象创建等问题,Scala可能会比Java慢数倍,就像在Java中使用不小心处理对象创建的库一样。实际上,我的Scala代码通常比我的Java代码更快,因为我发现使用Scala更容易使我的高度优化的代码方便使用和复用,但如果我有更多时间和耐心,Java也可以达到同样的速度或更快速度。

如果您想要一些数据来证明Scala基本上可以和Java一样快,请查看 计算机语言基准测试游戏的结果。(另一个对于高吞吐量多核编程不太有用但仍然有趣的比较是Tim Bray的Wide Finder 2。这个比较不太有用是因为算法没有事先定义,因此差异的很大程度上归结于算法上的区别。)


2
现代Java JVM 1.5中的对象创建几乎是免费的,这只是FUD。由于所有Scala特定语言功能的间接引用,Scala比本地Java慢,就像Groovy一样。与Java相比,在相同的JVM上预计会有多达5倍的速度惩罚。 - user177800
11
@Fuzzy: 你完全错误了,请看一下我链接的基准测试。它们支持你的立场吗?你可以发布其他支持你观点的测试结果吗?你是否进行过微基准测试来比较对象创建的速度和一层间接引用的速度,以及当JIT不真正需要时如何消除间接引用?(提示:我已经做过了,这就是为什么我发了我发的内容。) - Rex Kerr
10
我在此支持 Rex。创建对象是廉价的,但如果你在内部循环中所做的只是一小部分数学运算,则相比之下,对象的创建成本非常高昂。 - Daniel C. Sobral
3
@fuzzy: 对象的分配很便宜。而对象的初始化可能非常昂贵;即使是浅拷贝构造函数,如果创建足够多的对象,也可能需要大量时间。你知道,在函数式代码中经常调用的那种拷贝构造函数,因为你正在使用不可变对象而不是可变状态... - Porculus
@user1611728 - 在某些情况下,如果垃圾回收是“必须的”,JVM GC 的性能实际上比单独调用 malloc 要好得多。当然,如果您足够了解内存使用情况,您可以在像 C++ 这样的非 GC 语言中做得更好,因此,GC 可能会导致速度变慢。但这并不是一个明显的事实,即从 GC 切换到 malloc/free 风格的内存管理会改善事情。 - Rex Kerr
显示剩余3条评论

14

Scala被编译成字节码,是静态类型的语言,因此可以像Java这样的静态类型语言一样进行许多优化(与Groovy这样的动态类型语言相比不同)。因此,将Groovy与Scala进行比较就像是苹果与橘子的比较。

现在,Java和Scala之间的比较:

在大多数情况下,您可以期望Scala与Java处于相同水平。如果您以愚蠢的方式在Scala中编程,例如,通过Trait的许多混入可能会提供一些开销,而普通的Java则没有这种问题。

但是...

如果Trait实际上在良好的代码风格下解决了一个复杂的问题,那么使用纯Java进行解决同样的复杂性。谁能说你用自己的模式在Java中编写的解决方案比你在Scala中免费获得的更有效呢(请记住,Scala编译器是由比你更优秀的程序员编写的)。

另一方面,如果您没有充分的理由使用语言特性(例如,使用整型对象而不是简单的int基元),无论使用哪种语言,您的代码都将变得臃肿、缓慢、糟糕。

此外,请考虑与数据库或其他I/O密集型资源交互的请求-响应类特殊应用程序。瓶颈不会是“new”运算符或虚拟方法调用开销-几乎肯定是I/O。

总之,在Scala和Java之间的性能大致相同,在99%的情况下,这不应该是您选择其中一个的最大原因。由于熟练的人工劳动力比计算机硬件更昂贵,因此您最好选择您可以(或可以学会)在其中一种语言中编写代码最有效的语言(包括您的团队成员)。如果Scala让您编写的代码量只有Java的十分之一,那么使用它可能会获得10倍的收益。如果Scala使您变慢了10倍(因为太难读了),请坚持使用Java!


5
理论上这一切都是正确的。但实际上,如果你测量代码而不仅仅是期望代码,Scala 代码往往比 Java 代码慢得多,就像实际上 Java 代码往往比 C++ 代码慢一样。“不要担心速度,用硬件解决慢速代码”的论点每天都不再那么正确了。在客户端,网络本和手机都不快。服务器端,有减少能源使用的压力。我们不会回到手工调整的汇编语言,但值得仔细思考 Scala 给你带来了什么。 - Porculus
1
实际上,我还没有能够通过仅将程序从Scala移植到Java来遇到任何可衡量的加速。 - Seun Osewa
7
@Porculus:你是否有任何实际数据支持你的看法?虽然我同意你对Java/C++的比较,但我并不明白这如何适用于Scala与Java之间的比较。这就像争论GCC创建二进制文件通常会明显变慢,因为你在C++中使用了解析器A而不是解析器B一样。 - soc

5

我同意Rex在这篇文章中的评论,并且我有个人经历来支持它。我将一个Processing applet从Java转换到Scala,没有改变任何实现细节,两个applets都以大约6ms渲染一个框架,变化很小。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接