t-nissieの日記: 【電脳】Erlangで遊んでみた 1日目 その1 末尾再帰最適化 1
コンパイルしたときに末尾再帰最適化されたかどうかってわかるのかな?
* 再帰を用いて文字列を構成する単語の数を返す関数を書け.
* 再帰を用いてNまで数える関数を書け.
実行:
Erlang R15B02 (erts-5.9.2) [source] [smp:2:2] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9.2 (abort with ^G)
1> c(recursive).
recursive.erl:34: Warning: variable 'Current' is unused
{ok,recursive}
2> recursive:count_words("This is a pen.").
4
3> recursive:count_words("Hello.").
1
4> recursive:count_words("Hi ").
2
5> recursive:counter(5).
1
2
3
4
5
ok
6> recursive:counter(1).
1
ok
7> recursive:counter(0).
0
8> recursive:counter(-5).
-5
9>
code: recursive.erl
-module(recursive).
-export([factorial/1]).
-export([fibonacci/1]).
-export([fibonacci2/1]).
-export([counter/1]).
-export([count_words/1]).
%%% N!
factorial(0) ->
1;
factorial(N) ->
N * factorial(N-1).
%%% Fibonacci sequence (slow version)
fibonacci(0) ->
0;
fibonacci(1) ->
1;
fibonacci(N) ->
fibonacci(N-1) + fibonacci(N-2).
%%% Fibonacci sequence (fast tail-call-optimization version)
%%% http://en.literateprograms.org/Fibonacci_numbers_%28Erlang%29
fibonacci2_tr( 0, Result, _Next) ->
Result;
fibonacci2_tr(Iter, Result, Next) ->
fibonacci2_tr(Iter-1, Next, Result+Next).
fibonacci2(N) ->
fibonacci2_tr(N, 0, 1).
%%% count to N
counter_tr(1, Current) ->
io:format("~w~n",[Current]);
counter_tr(N, Current) when N < 1 ->
N;
counter_tr(N, Current) ->
io:format("~w~n",[Current]),
counter_tr(N-1, Current+1).
counter(N) ->
counter_tr(N,1).
%%% count the number of words in a string
count_words_tr([],Counter) ->
Counter+1;
count_words_tr([32|T],Counter) ->
count_words_tr(T,Counter+1);
count_words_tr([_|T],Counter) ->
count_words_tr(T,Counter).
count_words(T) ->
count_words_tr(T,0).
スタック消費量を (スコア:1)
プロファイラかデバッガか逆アセンブルで調べる、とか?
M-FalconSky (暑いか寒い)