3

私は再帰を試しています:

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():)

4

1 に答える 1