Поддерживает ли Scala оптимизацию хвостовой рекурсии?
Поддерживает ли Scala оптимизацию хвостовой рекурсии?
Ответ 1
Scala оптимизирует хвостовую рекурсию во время компиляции, как говорили другие плакаты. То есть, рекурсивная функция хвоста преобразуется в цикл компилятором (метод invoke преобразуется в скачок), как видно из трассировки стека при выполнении хвостовой рекурсивной функции.
Попробуйте следующий фрагмент:
def boom(n: Int): Nothing = if(n<=0) throw new Exception else boom(n-1)
boom(10)
и проверьте трассировку стека. Он покажет только один вызов функции boom - поэтому скомпилированный байт-код не является рекурсивным.
Есть предложение, плавающее вокруг реализовать хвостовые вызовы на уровне JVM - что, на мой взгляд, было бы здорово сделать, так как тогда JVM может выполнять оптимизацию во время выполнения, а не просто компилировать оптимизацию времени кода, и, возможно, это означает более гибкую рекурсию хвоста. В принципе, tailcall invoke
будет вести себя точно так же, как обычный метод invoke
, но сбросит стек вызывающего абонента, если это будет безопасно - спецификация состояний JVM, в которых должны храниться фреймы стека, поэтому JIT должен сделать некоторые статический анализ кода, чтобы узнать, не будут ли использоваться фреймы стека.
Текущий статус proto 80%. Я не думаю, что это будет сделано вовремя для Java 7 (invokedynamic
имеет больший приоритет, а реализация почти завершена), но Java 8 может увидеть, что он реализован.
Ответ 2
В 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)
}
Если метод не может быть оптимизирован, вы получите предупреждение.
Ответ 3
Scala 2.7.x поддерживает оптимизацию хвостового вызова для саморекурсии (функция, вызывающая себя) конечных методов и локальных функций.
Scala 2.8 может поставляться с поддержкой библиотеки для батута, что является методом оптимизации взаимно-рекурсивных функций.
Много информации о состоянии рекурсии Scala можно найти в блоге Rich Dougherty.
Ответ 4
Только в очень простых случаях, когда функция является саморекурсивной.
Доказательство способности рекурсии хвоста.
Похоже, что Scala 2.8 может улучшить распознавание хвостовой рекурсии.