私は再帰を試しています:
def fac
//fac = { int curr, res = 1G -> 1 >= curr ? res : fac( curr - 1, res * curr ) }
fac = { int curr, res = 1G -> 1 >= curr ? res : fac.trampoline( curr - 1, res * curr ) }
fac = fac.trampoline()
def rnd = new Random()
long s = System.currentTimeMillis()
100000.times{ fac rnd.nextInt( 40 ) }
println "done in ${System.currentTimeMillis() - s} ms / ${fac(40)}"
このように使用すると、次のようになります。
691ミリ秒で完了
行番号 2 のコメントを外し、行番号 3 ~ 4 のコメントを削除trampoline()
して実行すると、数値が大幅に低くなります。
335ミリ秒で完了
したがって、トランポリンを使用すると、再帰の動作が 2 倍遅くなります。
私は何が欠けていますか?
PS
Scala 2.12 で同じ例を実行すると、次のようになります。
def fac( curr:Int, acc:BigInt = 1 ):BigInt = if( 1 >= curr ) acc else fac( curr - 1, curr * acc )
val s = System.currentTimeMillis
for( ix <- 0 until 100000 ) fac( scala.util.Random.nextInt(40).toInt )
println( s"done in ${System.currentTimeMillis - s} ms" )
それは少し速く実行されます:
178ミリ秒で完了
アップデート
アノテーションを使用してクロージャーをメソッドに書き換えます。
@groovy.transform.TailRecursive
def fac( int curr, res = 1G ) { 1 >= curr ? res : fac( curr - 1, res * curr ) }
// the rest
与える
164ミリ秒で完了
そしてスーパーコールです。それにもかかわらず、私はまだ知りたいですtrampoline()
:)