2016年3月11日金曜日

Luaの末尾呼び出しの最適化

Luaの末尾呼び出しは最適化されるため、スタック領域を消費しない。
末尾呼び出しとは、関数A内の末尾で他の関数Bを呼び出することで、
関数Bの呼び出し後、他に処理が存在しない状態を指す。

通常は、関数呼び出しを行うと、呼び出す関数用にスタック領域を消費するが、
末尾呼び出しの場合は、消費されない。

(ex-1)
function foo(n)
    if n > 0 then return foo(n-1) end 
end

foo(1000000)

(ex-2)
function foo(n)
    if n > 0 then return (foo(n-1)) end 
end

foo(1000000)

上記はいずれも関数fooを1M回呼び出しているが、
(ex-1)は正常終了するものの、
(ex-2)はStack over flowで異常終了となる(※)。
(※)スタックの上限値による。上記例はスタック容量を1MByteとした場合の例。

(ex-2)の方は (foo(n-1)) のように関数呼び出しを括弧で括っており、
呼び出した後の戻り値を1つに調整するという処理が入るため、
末尾呼び出しとならず最適化が行われない。

0 件のコメント:

コメントを投稿