浅谈尾递归的优化方式
在上文《尾递归与Continuation》里,我们谈到了尾递归的概念和示例,不过有些朋友对于尾递归的 功效依然有所怀疑。因此现在,老赵再简单讲解一下尾递归的优化原理,希望能给大家以一定理性认识。 尾递归的循环优化 尾递归,即是递归调用放在方法末尾的递归方式,如经典的阶乘:
由于递归在方法的末尾,因此方法中的局部变量已经毫无用处,编译器完全可以将其“复用”,并把 尾递归优化为“循环”方式:
不过,上文还提到了尾递归中的常用技巧Continuation。那么对于如下形式的Continuation,编译器 又该如何优化呢?
我们先用“人脑”来思考一下,这段代码的执行方式是怎么样的。我们每次使用n和contn 调用FactorialContinuation时,都会构造一个新的contn - 1,并同n - 1传入下一次 FactorialContinuation调用中去。以此类推,直到n等于0时,就直接调用cont0并返回。至 于每个Continuation的定义,我们可以归纳出如下结果:
因此:
于是,我们可以根据这个“意图”,将FactorialContinuation方法“优化”为如下形式:
我们构造了一个Continuation函数链表,随着n递减,每次都会把新的Continuation函数插入到链表头 ,最后Aggregate方法会将第一个参数(累加器)依次运用到每个函数中去,得到最后结果并返回。只可 惜,这个优化完全是我们“一厢情愿”而已,这么做的前提是“理解”了函数的意义,把方法的迭代调用 “拆开”,而编译器是无法(还是很难)帮我们优化到如斯地步的。那么编译器对于此类问题又该如何解 决呢? 之前,我们使用C#中的匿名方法特性来构造每个Continuation方法。如果我们使用自定义的封装类, 再将递归“优化”成循环,FactorialContinuation又会成为什么样呢?如下:
|
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |