简体   繁体   English

更简单的递归代码运行速度比同一事物的迭代版本慢

[英]simpler recursive code runs slower than iterative version of the same thing

I wrote this python code to give the Harmonic Series of a certain value n both recursively and iteratively. 我编写了这个python代码,以递归和迭代的方式给出Harmonic Series一定值。 Here is the functions: 这是功能:

def H(n):
    if (n <= 0): raise ValueError("n must be bigger than 0.")
    if (n == 1): return 1
    else: return sum([1/x for x in range(1,n+1)])

def H_rec(n):
    if (n <= 0): raise ValueError("n must be bigger than 0.")
    if (n == 1): return 1
    else: return 1/n + H(n-1)

Then, when I run the code 10 times for each, I get the following times: 然后,当我为每个代码运行代码10次时,我得到以下时间:

RECURSIVE TIMES [22.755768060684204, 17.231882095336914, 14.965636014938354, 14.277509927749634, 14.0553719997406, 13.788002014160156, 13.338942766189575, 13.72638201713562, 14.690818071365356, 14.236813068389893] 
RECURSIVE MEAN: 15.30671260356903
ITERATIVE TIMES [15.093524932861328, 12.801156759262085, 13.350629091262817, 13.806081056594849, 13.29387378692627, 13.876484870910645, 12.934008121490479, 13.859009981155396, 13.350301027297974, 13.590226888656616] 
ITERATIVE MEAN: 13.595529651641845

The code is supposed to find H_rec(100000000) and H(100000000) , which are fairly big numbers. 代码应该找到H_rec(100000000)H(100000000) ,它们是相当大的数字。

I don't understand exactly why the recursive definition takes longer when the way it's defined seems to require less computation. 我不明白为什么递归定义需要更长时间,因为它的定义方式似乎需要更少的计算。 The iterative one requires forming a list and finding its sum, while the recursive one just sums 1/n + H(n-1) . 迭代的一个需要形成一个列表并找到它的总和,而递归的一个只是总和1/n + H(n-1)

What is so misleading about this recursion? 这次递归有什么误导? Why is it slow? 它为什么慢?

Your recursive function is calling the iterative one in else: return 1/n + H(n-1) , you need to modify it as the following: 你的递归函数在else: return 1/n + H(n-1)调用迭代函数else: return 1/n + H(n-1) ,你需要修改它如下:

def H_rec(n):
    if (n <= 0): raise ValueError("n must be bigger than 0.")
    if (n == 1): return 1
    else: return 1/n + H_rec(n-1) #Fix this line

Code executed inside the Python interpreter is fastest. 在Python解释器中执行的代码是最快的。 Python code (which is compiled to Python byte code that is interpreted by a virtual machine) is slower. Python代码(编译为由虚拟机解释的Python字节代码)较慢。 User-defined function calls are slowest of all, because the virtual machine has to manage its own call stack to track the execution environments. 用户定义的函数调用是最慢的,因为虚拟机必须管理自己的调用堆栈以跟踪执行环境。

Consider the following code: 请考虑以下代码:

def S1(n):
    return sum(range(1,n))

def S2(n):
    rv = 0
    for i in range(1,n):
        rv += i
    return rv

def S3(n):
    if n == 0:
        return 0
    else:
        return n + S3(n-1)

S1 is the fastest; S1是最快的; as much work as possible is pushed into the interpreter. 尽可能多的工作被推入翻译。 S2 is slower because now each addition is a separate Python instruction to be interpreted. S2较慢,因为现在每个添加都是一个单独的Python指令来解释。 S3 is slowest because now each addition involves another function call to get its second operand; S3是最慢的,因为现在每次添加涉及另一个函数调用以获得其第二个操作数; as noted before, function calls are slow in Python. 如前所述,函数调用在Python中很慢。

>>> print(timeit.timeit('S1(50)', globals=globals()))
1.2118524569996225
>>> print(timeit.timeit('S2(50)', globals=globals()))
3.262354401002085
>>> print(timeit.timeit('S3(50)', globals=globals()))
10.102635376999388

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM