为什么Scala for循环比逻辑上相同的循环慢?

use*_*301 5 scala

我喜欢Scala的强大功能以及它们与任何monadic类型与map和flatMap集成的方式.但是,我还想做一个简单的整数循环而不会有很大的速度惩罚.为什么Scala没有以下两个逻辑上相同的循环以相似的运行时性能运行甚至编译成类似的字节代码?

// This is slow...
for (i <- 0 until n) println(s"for loop with $i")

// This runs much faster. It runs roughly at the same speed as Java code doing an identical while or for loop.
var i = 0;
while (i < n) {
  println(s"while loop with $i")
  i += 1
}
Run Code Online (Sandbox Code Playgroud)

Kev*_*ght 6

他们不同的主要原因(但不仅仅是)是拳击.

在代码中:

for (i <- 0 until n) println(s"for loop with $i")
Run Code Online (Sandbox Code Playgroud)

你将一个匿名函数传递println(s"for loop with $i")给了解for (i <- 0 until n).它相当于:

(0 until n) foreach (i =>
  println(s"for loop with $i")
}
Run Code Online (Sandbox Code Playgroud)

该函数在字节码中被删除,这意味着它i不能是一个原语int,它必须被装箱Integer.Java没有Fixnum引用来避免这种成本,就像Smalltalk那样(特别令人沮丧的是,考虑到旧的smalltalk有多少!)

-optimize在某些情况下使用可以提供帮助,特别是在scalac的主干版本中.

你也可以使用scalaxy/loops来加快速度:)

  • @ user2684301这将是跨项目的优化,当前稳定的编译器无法做到。“ Range.foreach”具有* Generic *函数,因此优化将需要将“ foreach”的实现从标准库复制到使用代码中,然后进行专门化-这会带来各种乐趣,实现二进制兼容性。 (2认同)