我正在阅读一本关于Erlang的书,我从书中举了一个简单的例子。
%% exrs.erl
-module(exrs).
-export([sum/1]).
sum(0) -> 0;
sum(N) -> N + sum(N - 1).
当我运行这个例子的大数字(i.g. 1000000000)它使用16Gb内存和48Gb交换文件在我的PC上计算这个函数。
1> exrs:sum(1000000000).
这是Erlang VM的常见行为吗?如何避免这样的问题?
附言:
10> erlang:system_info(version).
"11.1"
11> erlang:system_info(otp_release).
"23"
操作系统:Windows 7
2条答案
按热度按时间5w9g7ksd1#
正如在其他答案中所说的,你的递归不是尾部优化的。在你的代码中发生的是,erlang计算表达式的右侧,并递归地将新的函数调用追加到堆栈中。如下所示
1_000_000 + sum(999_999 + sum(999_998 + sum(....)))
正确的方法是编写一个接受累加器作为sum函数的第二个参数的函数,如下所示
6xfqseft2#
你的递归函数不能使用尾部调用优化,所以它为每个递归调用使用一个堆栈帧。
1,000,000,000次递归调用是很多堆栈帧。
例如,请参见“学习一些Erlang”这一节,了解更多细节。