При написании функции, как факториал:инструменты производительности для Эрл
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).
Или, возможно, даже defunctionalized:
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}).
Сроки этих трех реализаций Я обнаружил, что время выполнения, как и ожидалось, такое же.
Мой вопрос в том, есть ли способ получить более подробные знания, чем это? Как я могу, например, получить использование памяти для выполнения функции - я вообще избегаю какой-либо памяти стека?
Что такое стандартные инструменты для проверки таких вещей?
Вопросы снова, как я могу определить высоту стека функций, как определить использование памяти для вызова функции на каждом из них и, наконец, какой из них лучше?
Одна из вещей, которые мне интересны в том, чтобы выяснить, насколько работает LCO erlang, без меня спрашивает, и когда имеет смысл делать это самостоятельно, и я просто хотел это проверить.Я знаю, что последняя версия будет оптимизирована, но как насчет первой, будет ли «X * F (X -1, F)» означать, что мы получаем стек из X, который затем умножается вместе, хотя стек? –
Нет. Оливье, вероятно, написало бы '(* X (F (-1 X) F))' или что-то подобное в Схеме, и тогда довольно ясно, что последнее, что делает предложение функции, - это умножение, а не вызов функции. Следовательно, TCO/LCO не может применяться и не оптимизируется. * Другое * вещь, на которую нужно обратить внимание, - это попытка ... catch, которая толкает обработчик в стек, который раскручивает его, даже если ваш вызов находится в хвостовой позиции. –
он бы, и, насколько я помню, он не самый большой поклонник мира Эрланг ... –