例えば、Nの階乗を計算するように慣れていない再帰関数、:
関数 F($ N ){ 場合($ N <= 1)リターン 1 。 返す $ N * F($ Nを -1 ;) }
もちろん、人は書くかもしれません。
関数 F($ N、$結果){ 場合($ N <= 1)を返す $結果。 リターン F($ N -1、$ N * $結果); }
見て二つの方法上記の有意差はないように見えますが、CPUの目には、同じではないかもしれません。
分析
スタックを開きます関数呼び出しが、関数呼び出しの端部が破壊されるスタックポインタ、戻り値及び他の情報に、ローカル変数、パラメータの機能を保持する機能。再帰関数は、上側のスタックの機能は、再帰終了を知ることができませんすべてのアウトを常に再帰破壊されています。
呼び出すときに栗の場合は、f(3)
時間を、スタックの機能、上記の最初のケースは、おそらく(唯一の他のコンテンツを無視して、保持パラメータと戻り値は、)長い道のりです。
テキストの説明は次のとおりです。
F(1)= 1
F(2)= 2 * F(1)= 2 * 1 = 2
F(3)= 3 * F(2)= 3 * 2 = 6
F(4)= 4 * F(3)= 4 * 6 = 24
すなわち、各呼び出しは、神があまりにも多くのメモリを開放する場合は、あまりにも再帰的につながるだろう再帰呼び出し、この変数nと戻り値に保存されます。
2番目の文言を使用している場合は、何が違うのでしょうか?
ただ、記述するための最初の単語を解析を適用します。
F(4,1)= F(3、4 * 1)= F(2、3 * 4)= F(1、2 * 12)= 24
持っているが、差は認められない、違いは、前者の文言を使用すると、ローカル変数n、後者の文言を保存したいということである、パラメータは次の方法で書かれています。換言すれば、第2の方法は、あなたが基本となるメソッドに直接返すことができ、あなたがアップ戻ってする必要はありません。もちろん、CPUが言うことです機能スタック、状況について、このような機能スタックを多重化、この場合が見つかりました:
鑑賞異なる何もないように見えるが、!ダイレクトリターンなので、4のスタックは、図に使用されるのと同じスタックです。
再帰再帰呼び出しが返され、直接コールのリターンを話しているとき、などの操作、に参加しなかったので、再利用・スタックを最適化されます。