code

Scala는 꼬리 재귀 최적화를 지원합니까?

codestyles 2020. 11. 27. 08:08
반응형

Scala는 꼬리 재귀 최적화를 지원합니까?


Scala는 꼬리 재귀 최적화를 지원합니까?


Scala는 다른 포스터가 말했듯이 컴파일 타임에 꼬리 재귀 최적화를 수행합니다. 즉, 꼬리 재귀 함수를 실행할 때 스택 추적에서 볼 수 있듯이 컴파일러에 의해 꼬리 재귀 함수가 루프로 변환됩니다 (메소드 호출이 점프로 변환 됨).

다음 스 니펫을 시도하십시오.

def boom(n: Int): Nothing = if(n<=0) throw new Exception else boom(n-1)
boom(10)

스택 추적을 검사하십시오. boom 함수에 대한 호출이 하나만 표시되므로 컴파일 된 바이트 코드는 재귀 적이 지 않습니다.

JVM 수준에서 테일 호출구현 하기위한 제안 이 떠돌고 있습니다 . 제 생각에는 JVM이 코드의 컴파일 시간 최적화보다는 런타임 최적화를 수행 할 수 있으므로 더 많은 것을 의미 할 수 있습니다. 유연한 꼬리 재귀. 기본적으로 a tailcall invoke는 일반 메서드와 똑같이 동작 invoke하지만 안전 할 때 호출자의 스택을 삭제합니다. JVM 사양에 스택 프레임을 보존해야한다고 명시되어 있으므로 JIT는이를 파악하기 위해 몇 가지 정적 코드 분석을 수행해야합니다. 스택 프레임이 사용되지 않는 경우.

현재 상태는 proto 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는 최종 메서드 및 로컬 함수의 자체 재귀 (자신을 호출하는 함수)에 대한 테일 호출 최적화를 지원합니다.

Scala 2.8은 상호 재귀 함수를 최적화하는 기술인 트램폴린에 대한 라이브러리 지원도 제공 할 수 있습니다.

Scala 재귀 상태에 대한 많은 정보는 Rich Dougherty의 블로그 에서 찾을 수 있습니다 .


함수가 자체 재귀적인 매우 간단한 경우에만 해당됩니다.

꼬리 재귀 능력 증명.

하지만 Scala 2.8은 꼬리 재귀 인식을 향상시킬 수 있습니다.

참고 URL : https://stackoverflow.com/questions/1677419/does-scala-support-tail-recursion-optimization

반응형