现如今,递归的效率到底有多差

2015-09-15 20:18:03 +08:00
 snailsir

时常会遇到一些人在我说出递归时反驳说,递归的效率很差。好像还记得大学学 C 语言时,谭浩强也这么写过,老师也这样教我们。

但,我在接触 lisp 之后,却发现处处都有递归的思想及应用,也没发现有什么差的地方,反倒是处理问题简单许多。

所以始终不明白递归的效率到底有多差。一点猜测是,那个时候,计算机很奢侈;但现如今,随便一台电脑,性能都很好啊。

5209 次点击
所在节点    编程
12 条回复
ruandao
2015-09-15 20:44:35 +08:00
你那个是迭代,只是用递归的形式显示
snailsir
2015-09-15 20:47:56 +08:00
@ruandao
ch3n2k
2015-09-15 20:48:56 +08:00
尾递归可以用,在支持尾递归优化的语言里面
monsoon
2015-09-15 20:48:56 +08:00
有种递归叫尾递归。
mthli
2015-09-15 20:52:19 +08:00
是的,有种递归叫尾递归。
caixiexin
2015-09-15 20:54:09 +08:00
不是效率差,而是递归会导致内存溢出,尾递归除外- -
ruandao
2015-09-15 21:24:38 +08:00
YuJianrong
2015-09-15 21:46:38 +08:00
1. 递归性能是真的差, call 一个函数的时候大多数语言都需要有一定程度的资源分配、释放等操作,这当然要比单纯循环性能更差。
2. 为了能回溯,递归函数的参数和地址需要分配在 call stack 上,大部分语言的 call stack 大小都是有限的,递归太深就会爆掉
3. 没有 side effect 的语言(如 lisp, haskell )当递归在尾部的时候可以做尾递归优化,这时函数其实并没有递归而被优化成循环了(实际上 lisp 没有循环本来做循环就得靠尾递归)。

顺便黑一下 lisp ,这玩意玩玩就好其实根本不能适应现代大规模开发,我看还是学好 C++/java/JS 比较实在。
ryd994
2015-09-15 21:58:45 +08:00
处理问题简单和性能好有什么关系?
有尾递归优化时,开销相对较小,但也无非就是循环而已,考虑到初始化之类的成本,还是不如循环。
没尾递归你就等着深度大的时候爆栈吧
其实递归就是利用函数调用的机制做循环而已
pynix
2015-09-15 23:27:05 +08:00
优化。。。。
snailsir
2015-09-16 09:50:47 +08:00
看到大家的回答,总结一下问题所在吧:

1. 说开销,感觉还是在 函数调用堆栈 上面,这个各语言是的限制又不一样。
2. 尾递归的话,得需要语言的支持。

但感觉以上两点,也并没有限制 递归的扩张啊。就像当年的 goto 语句一样( linux 内核源码风格中提到了在什么情况下比较适合使用 goto )

@ruandao 的例子然我想起了 lisp 里的做法貌似大都这样的,试了一下 php 版本的,居然也可以。



@ryd994
@YuJianrong
ryd994
2015-09-16 10:26:22 +08:00
@snailsir 限制再不一样,优化的再好,还是有,而且不会小。递归真心只有设计算法的时候感觉好。实现的时候就是大坑。出错的时候 debug 也更麻烦。 lisp 本来就是理论性很强的语言,感觉好不奇怪。 C 里面爆栈太容易。你确定递归用的很多?确实有递归好用的情况,但大多数情况都不是这样。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/220946

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX