【发布时间】:2019-07-17 09:51:03
【问题描述】:
我比较了循环和递归的运行时间,发现循环速度更快,同时没有遇到 RecursionError 的问题。为什么循环这么快?
def factorial(n):
if n == 0:
return n
else:
return n + factorial(n-1)
%%timeit -n1000 -r10000
factorial(1000)
每个循环 163 µs ± 13.2 µs(10000 次运行的平均值 ± 标准偏差,每次 1000 个循环)
def factorial2(n):
r = 0
for i in range(n+1):
r += i
return r
%%timeit -n1000 -r10000
factorial2(1000)
最慢的运行时间是最快的运行时间的 9.46 倍。这可能意味着正在缓存中间结果。 每个循环 58.7 µs ± 25.2 µs(10000 次运行的平均值 ± 标准偏差,每次 1000 个循环)
感谢和愉快的编码!
【问题讨论】:
-
一般来说,使用递归,运行时必须做额外的工作,将变量推送到堆栈帧,然后进行函数调用,这会增加执行时间。即使您一遍又一遍地调用相同的函数,使用递归,每次调用都会创建所有局部变量的新范围。通过迭代,不需要完成额外的工作。
-
你的
factorial实际上是在计算0 -> nbtw之间的总和 -
函数调用在 Python 中非常昂贵。一个神话是 Python 中的 for 循环很慢,但如果循环包含函数调用甚至方法调用,情况就很普遍。请参阅 wiki.python.org/moin/PythonSpeed/PerformanceTips 和 python.org/doc/essays/list2str 。所以
r += i比调用n + factorial(n-1)快很多。顺便说一句,阶乘不应该使用乘法吗?
标签: python python-3.x algorithm loops recursion