我喜欢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
}
答案 0 :(得分:6)
他们不同的主要原因(但不仅仅是)是拳击。
在代码中:
for (i <- 0 until n) println(s"for loop with $i")
您正在将匿名函数println(s"for loop with $i")
传递给理解for (i <- 0 until n)
。它相当于:
(0 until n) foreach (i =>
println(s"for loop with $i")
}
该函数在字节码中被删除,这意味着i
不能是原始int
,而是必须将其装箱为Integer
。 Java没有Fixnum引用来避免这种成本,就像例如Smalltalk确实如此(特别令人沮丧的是,考虑到旧的smalltalk多少!)
在某些情况下,使用-optimize
会有所帮助,尤其是在scalac的主干版本中。
您还可以使用scalaxy/loops来加快速度:)