Labfans是一个针对大学生、工程师和科研工作者的技术社区。 论坛首页 | 联系我们(Contact Us)
MATLAB爱好者论坛-LabFans.com
返回   MATLAB爱好者论坛-LabFans.com > 其它 > 资料存档
资料存档 资料存档
回复
 
主题工具 显示模式
旧 2019-12-14, 20:13   #1
poster
高级会员
 
注册日期: 2019-11-21
帖子: 3,006
声望力: 66
poster 正向着好的方向发展
帖子 MATLAB是否执行尾部调用优化?

我最近学习了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进行的总体拥有成本不符;函数仅在一个地方尾部调用自身而没有局部变量(除了单个参数)的情况,就像任何人都希望的那样简单。

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

在我们不花钱的情况下,递归要花多少钱?请看我对Bill Cheatham的回答的评论:看起来时间开销是不平凡的,但并非疯狂。

...除了我发表评论后,比尔·希瑟姆(Bill Cheatham)删除了他的答案。好。因此,我采用了Fibonacci函数的简单迭代实现和简单的尾递归函数,在这两个函数中进行了基本上相同的计算,并将它们都定时在fib(60) 。递归实现的运行时间比迭代实现的时间长约2.5倍。当然,对于执行更多工作而不是每次迭代进行一次加法和一次减法的函数,相对开销将较小。

(我也同意delnan的观点:在Haskell中感觉很自然的那种高度递归的代码在MATLAB中通常很容易理解。)



更多&回答...
poster 当前离线   回复时引用此帖
回复

主题工具
显示模式

发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛禁用 表情符号
论坛启用 [IMG] 代码
论坛启用 HTML 代码



所有时间均为北京时间。现在的时间是 22:48


Powered by vBulletin
版权所有 ©2000 - 2025,Jelsoft Enterprises Ltd.