Scala是否支持尾recursion优化?
Scala是否支持尾recursion优化?
正如其他海报所说,斯卡拉在编译时做了recursion优化。 也就是说,一个尾recursion函数被编译器转换成一个循环(一个方法调用被转换成一个跳转),从运行一个尾recursion函数时的栈跟踪中可以看出。
尝试以下代码片段:
def boom(n: Int): Nothing = if(n<=0) throw new Exception else boom(n-1) boom(10)
并检查堆栈跟踪。 它只会显示一个调用函数的繁荣 – 因此编译的字节码不是recursion的。
有一个提议在JVM级别上实现尾调用 – 在我看来这是一个很好的事情,因为JVM可以进行运行时优化,而不是编译代码的时间优化 – 可能意味着更多灵活的尾recursion。 基本上, tailcall invoke
行为与普通的方法invoke
完全相同,但是在安全的情况下会tailcall invoke
者的堆栈–JVM的规范说明了堆栈帧必须被保留,所以JIT必须做一些静态代码分析找出堆栈帧是否永远不会被使用。
目前的状况是原80% 。 我不认为Java 7会及时完成( invokedynamic
具有更高的优先级,实现几乎完成),但是Java 8可能会看到它的实现。
在Scala 2.8中,您可以使用@tailrec
来标记希望编译器优化的特定方法:
import scala.annotation.tailrec @tailrec def factorialAcc(acc: Int, n: Int): Int = { if (n <= 1) acc else factorialAcc(n * acc, n - 1) }
如果一个方法不能优化,你会得到一个警告。
Scala 2.7.x支持最终方法和本地函数的自recursion(自我调用函数)的尾调优化。
Scala 2.8也可能带有对蹦床的库支持,这是一种优化相互recursionfunction的技术。
关于Scalarecursion状态的大量信息可以在Rich Dougherty的博客中find 。
只有在函数是自recursion的非常简单的情况下。
certificate尾recursion能力。
看起来Scala 2.8可能会改善尾recursion识别。