python 在这么算 fibonacci 的时候到底在干什么!?

2014-10-22 20:23:31 +08:00
 juicy
这几天学了点python,有一道题是让练习用python计算fibonacci数列,发现个很有意思的事:
当用传统的写法
return fib(n-1) + fib(n-2)
来算fib(40)的时候,算得超级慢,分钟级别的
而用generator的时候
def fib():
a = 1
b = 2
while 1:
a, b = b, (a+b)
yield a
counter = 0
for n in fib():
if counter == 40:
print n
break
counter +=1
瞬间就计算完了

后来,在这个链接里http://fengmk2.cnpmjs.org/blog/2011/fibonacci/nodejs-python-php-ruby-lua.html 发现了各种语言算fib(40)的效率

我很纳闷的是:
最后几种语言花费的时间跟python一样,都竟然达到1m,2m,甚至3m,
说得夸张一点,人脑算得都比它们快,
那么,问题来了,如题
4589 次点击
所在节点    Python
28 条回复
jox
2014-10-22 23:30:30 +08:00
额,v2ex会把前面的空格都处理掉啊,晕了
xarrow
2014-10-22 23:55:03 +08:00
Python 切片 尾调,明天贴代码!
songco
2014-10-22 23:58:23 +08:00
其实n不大的情况下, 直接用公式比较好:
f(n)=(√5/5)*{[(1+√5)/2]^n - [(1-√5)/2]^n}
jox
2014-10-23 00:08:15 +08:00
python对递归深度有限制,默认好像超过1000就不让算了,因为python不支持尾递归优化,所以即使写成尾递归的形式也不会节省资源,但是只要不超过默认的递归深度计算速度也是非常快的,不过有个技巧可以让尾递归形式的函数超过递归深度,就像这样:

monkeylyf
2014-10-23 04:28:17 +08:00
一个是递归没有memorization 一个是类似dp的O(n) 当然后者快啦
juicy
2014-10-23 08:35:29 +08:00
多谢各位,受益匪浅~
hahastudio
2014-10-23 11:51:03 +08:00
Python Tail Call Optimization Decorator
http://code.activestate.com/recipes/474088-tail-call-optimization-decorator/

顺带一提,v2ex 贴代码可以用 gist
leopanhf
2014-10-29 15:50:21 +08:00
我觉得楼主其实不太理解 yield 吧??

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

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

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

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

© 2021 V2EX