php专区

 首页 > php专区 > PHP进阶 > 算法 > 漫谈递归:PHP里的尾递归及其优化

漫谈递归:PHP里的尾递归及其优化

分享到:
【字体:
导读:
         摘要:事实证明,尾递归在php中是没有任何优化效果的。一般的线性递归修改成为尾递归最大的优势在于减少了递归调用栈的开销。从php那个例子就明显看出来递归开销对程序的影响。但是并不是所有语言都支持尾递归的,即使支持尾递归的语言也一般是在编译阶段对尾递归进行优化,比如C语言对尾递归的优化。 ...

漫谈递归:PHP里的尾递归及其优化

不同的语言对尾递归的支持都有所不同,编译器的优化也不尽相同。我们之前看了C语言的尾递归,那么在PHP里又是如何的呢?

PHP对尾递归没有优化效果

先来看下实验。


如果安装了XDebug的话,可能会遇到如下错误:

Fatal error: Maximum function nesting level of '100' reached, aborting!

这是XDebug的一个保护机制,可以通过max_nesting_level选项来设置。放开设置的话,程序还是能够正常运行的。

即便代码能正常运行,只要我们不断增大参数,程序迟早会报错:

Fatal error:  Allowed memory size of … bytes exhausted

为什么呢?简单点说就是递归造成了栈溢出。按照之前的思路,我们可以试下用尾递归来消除递归对栈的影响,提高程序的效率。


XDebug同样报错,并且程序的执行时间并没有明显变化。

Fatal error: Maximum function nesting level of '100' reached, aborting!

事实证明,尾递归在php中是没有任何优化效果的。

PHP如何消除递归

先看看下面的源代码:


现在XDebug不再警报效率问题了。

注意到trampoline()函数没?简单点说就是利用高阶函数消除递归。想更进一步了解 call_user_func_array,可以参看这篇文章:PHP函数补完:call_user_func()与call_user_func_array()

还有很多别的方法可以用来规避递归引起的栈溢出问题,比如说Python中可以通过装饰器和异常来消灭尾调用,让人有一种别有洞天的感觉。

小结

在C中的尾递归优化是gcc编译器做的。一般的线性递归修改成为尾递归最大的优势在于减少了递归调用栈的开销。从php那个例子就明显看出来递归开销对程序的影响。但是并不是所有语言都支持尾递归的,即使支持尾递归的语言也一般是在编译阶段对尾递归进行优化,比如C语言对尾递归的优化。在使用尾递归对代码进行优化的时候,必须先了解这门语言对尾递归的支持。

在PHP里,除非能提升代码可读性,否则没有必要使用递归;迫不得已之时,最好考虑使用Tail Call或Trampoline等技术来规避潜在的栈溢出问题。

延伸阅读

此文章所在专题列表如下:

  1. 漫谈递归:递归的思想
  2. 漫谈递归:递归需要满足的两个条件
  3. 漫谈递归:字符串回文现象的递归判断
  4. 漫谈递归:二分查找算法的递归实现
  5. 漫谈递归:递归的效率问题
  6. 漫谈递归:递归与循环
  7. 漫谈递归:循环与迭代是一回事吗?
  8. 递归计算过程与迭代计算过程
  9. 漫谈递归:从斐波那契开始了解尾递归
  10. 漫谈递归:尾递归与CPS
  11. 漫谈递归:补充一些Continuation的知识
  12. 漫谈递归:PHP里的尾递归及其优化
  13. 漫谈递归:从汇编看尾递归的优化

本文地址:http://www.nowamagic.net/librarys/veda/detail/2334,欢迎访问原出处。

漫谈递归:PHP里的尾递归及其优化
分享到:
漫谈递归:从汇编看尾递归的优化
漫谈递归:从汇编看尾递归的优化 对于尾递归,很多人的理解仅局限于它是递归和尾调用的一个合体,比普通递归效率高。至于效率为什么高,高在哪,可能没有深究过。? 尾调用 要说尾递归,得先说尾调用。我理解的尾调用大概是这么一种情况: 函数A里面调用了函数B。 函数B执行后,函数A马上返回。 也就是说调用函数B...
漫谈递归:补充一些Continuation的知识
漫谈递归:补充一些Continuation的知识 尾递归与Continuation的联系 前面谈了尾递归与Continuation,但是感觉还有些要补充下。 Continuation是一种非常古老的程序结构,简单说来就是entire default future of a computation, 即对程序“接下来要做的事情”所进行的一种建模,即为“完成某件事情”之后“还需要做的...
  •         php迷,一个php技术的分享社区,专属您自己的技术摘抄本、收藏夹。
  • 在这里……