在编写像阶乘这样的函数时:
fac(Val) when is_integer(Val)->
Visit = fun (X, _F) when X < 2 ->
1;
(X, F) ->
X * F(X -1, F)
end,
Visit(Val, Visit).
不禁会注意到尾调用优化并不是直截了当的,但是以连续解析的方式编写它是:
fac_cps(Val) when is_integer(Val)->
Visit = fun (X, _F, K) when X < 2 ->
K (1);
(X, F, K) ->
F(X-1, F, fun (Y) -> K(X * Y) end)
end,
Visit(Val, Visit, fun (X) -> X end).
或者甚至可能被取消功能:
fac_cps_def_lambdas({lam0}, X) ->
X;
fac_cps_def_lambdas({lam1, X, K}, Y) ->
fac_cps_def_lambdas(K, X*Y).
fac_cps_def(X) when is_integer(X) ->
fac_cps_def(X, {lam0}).
fac_cps_def(X, K) when X < 2 ->
fac_cps_def_lambdas(K,1);
fac_cps_def(X, K) ->
fac_cps_def(X-1, {lam1, X, K}).
对这三个实现进行计时,我发现执行时间和预期的一样。
我的问题是,有没有办法获得比这更详细的知识?例如,我如何获得执行函数的内存使用情况——我是否完全避免了任何堆栈内存?
检查这些东西的标准工具是什么?
问题又是,我如何测量函数的堆栈高度,如何确定每个函数调用的内存使用情况,最后,哪一个最好?