matlab - MATLAB 是否执行尾调用优化?

标签 matlab functional-programming tail-recursion tail-call-optimization

我最近学习了 Haskell,并尝试尽可能将纯函数式风格应用到我的其他代码中。这方面的一个重要方面是将所有变量视为不可变的,即常量。为此,许多本应使用命令式循环实现的计算必须使用递归来执行,这通常会因为每个函数调用分配新的堆栈帧而导致内存损失。然而,在尾调用的特殊情况下(被调用函数的返回值立即返回给被调用者的调用者),这种惩罚可以通过称为尾调用优化的过程来绕过(在一种方法中,这可以通过本质上是在正确设置堆栈后用 jmp 替换调用)。 MATLAB 是默认执行 TCO,还是有办法告诉它这样做?

最佳答案

如果我定义一个简单的尾递归函数:

function tailtest(n)
  if n==0; feature memstats; return; end
  tailtest(n-1);
end

并调用它,以便它可以非常深入地递归:

set(0,'RecursionLimit',10000);
tailtest(1000);

那么看起来堆栈框架并没有占用大量内存。但是,如果我让它递归得更深:

set(0,'RecursionLimit',10000);
tailtest(5000);

然后(今天在我的机器上)MATLAB 简单地崩溃了:进程突然终止。

我认为这与 MATLAB 执行任何 TCO 不一致;一个函数只在一个地方尾调用自己,除了一个参数之外没有局部变量的情况,就像任何人所希望的一样简单。

所以:不,似乎 MATLAB 根本不执行 TCO,至少在默认情况下是这样。我还没有(到目前为止)寻找可能启用它的选项。如果有的话我会很惊讶。

在我们不炸毁堆栈的情况下,递归的成本是多少?请参阅我对 Bill Cheatham 的回答的评论:看起来时间开销很重要,但并不疯狂。

...除了 Bill Cheatham 在我发表评论后删除了他的回答。好的。因此,我采用了 Fibonacci 函数的简单迭代实现和简单的尾递归函数,在两者中执行基本相同的计算,并在 fib(60) 上对它们进行计时。递归实现的运行时间比迭代实现的运行时间长 2.5 倍。当然,对于比每次迭代一次加法和一次减法做更多工作的函数,相对开销会更小。

(我也同意 delnan 的观点:在 Haskell 中感觉很自然的那种高度递归代码在 MATLAB 中通常很可能是单调的。)

关于matlab - MATLAB 是否执行尾调用优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5326749/

相关文章:

machine-learning - 我们如何在数据集上使用无监督学习技术,然后标记集群?

matlab - 如何在 Matlab 中将字符串转换为函数句柄?

c# - 返回与自身相同类型的委托(delegate)的委托(delegate)类型是否有用?

scheme - 这是尾递归吗?

matlab - 阻止我的文档中的 "MATLAB"文件夹

matlab - 按指定顺序创建 1 的数组

performance - 推理 Haskell 的性能

java - 通过流和平面图传递对象

function - F#:递归函数:连接两个列表之间的公共(public)值

c - 为什么我们不能使用静态变量来实现尾递归呢?