Python uses the decorator to optimize the example of tail recursion. python Recursion

Source: Internet
Author: User

Python uses the decorator to optimize the example of tail recursion. python Recursion

Introduction to tail recursion
Tail recursion is the function that returns the last operation that is a recursive call, and the function is tail recursion.
Recursion is linear. For example, each call to the factorial function creates a new stack (last-in-first-out) and uses continuous stack pressure to create recursion, stack Overflow is easily caused. Tail recursion uses the current stack to optimize recursive functions through data coverage.
The factorial function factorial completes tail recursion by passing the calculated value. However, python does not require the compiler to optimize tail recursion. Therefore, an error will still be reported when recursion is performed multiple times ).

Eg:

def factorial(n, x):  if n == 0:    return x  else:    return factorial(n-1, n*x)print factorial(5, 1) # 120

Tail recursion Optimization
Here we use the Fibonacci number as an example. The linear recursive algorithm is passed out because it is too inefficient. Let's take a look at the call in the method of delivery at the end:

(n,b1=1,b2=1,c=3): if n<3:  return 1 else:  if n==c:   return b1+b2  else:   return Fib(n,b1=b2,b2=b1+b2,c=c+1)

To test this program, call Fib (1001:

>>> def Fib(n,b1=1,b2=1,c=3):...  if n<3:...   return 1...  else:...   if n==c:...    return b1+b2...   else:...    return Fib(n,b1=b2,b2=b1+b2,c=c+1)... >>> Fib(1001)70330367711422815821835254877183549770181269836358732742604905087154537118196933579742249494562611733487750449241765991088186363265450223647106012053374121273867339111198139373125598767690091902245245323403501L>>> 

If we use Fib (1002), the result is as follows:

 ..... File "<stdin>", line 8, in Fib File "<stdin>", line 8, in Fib File "<stdin>", line 8, in Fib File "<stdin>", line 8, in Fib File "<stdin>", line 8, in Fib File "<stdin>", line 8, in FibRuntimeError: maximum recursion depth exceeded>>> 

Now let's optimize the tail recursion.

Add a Decorator to the Fib function, as shown below:

@tail_call_optimizeddef Fib(n,b1=1,b2=1,c=3): if n<3:  return 1 else:  if n==c:   return b1+b2  else:   return Fib(n,b1=b2,b2=b1+b2,c=c+1)

 
Well, this is the decorator @ tail_call_optimized. This decorator makes Python magically break the call stack restrictions.

Even if we run Fib (20000), we can run the results in 2000 ms (MS is the result of the Yuan netbook mentioned in the previous blog)

Let's take a look at the Magic Code below:

class TailRecurseException:  def __init__(self, args, kwargs):  self.args = args  self.kwargs = kwargs  def tail_call_optimized(g):  """  This function decorates a function with tail call  optimization. It does this by throwing an exception  if it is it's own grandparent, and catching such  exceptions to fake the tail call optimization.   This function fails if the decorated  function recurses in a non-tail context.  """  def func(*args, **kwargs):  f = sys._getframe()  if f.f_back and f.f_back.f_back and f.f_back.f_back.f_code == f.f_code:   raise TailRecurseException(args, kwargs)  else:   while 1:   try:    return g(*args, **kwargs)   except TailRecurseException, e:    args = e.args    kwargs = e.kwargs  func.__doc__ = g.__doc__  return func

The methods used have been shown before. I am very impressed by the fact that the author throws an exception and captures it to break the growth of the Call Stack, which is simply incredible. In addition, the efficiency problem is about five times the time overhead compared with direct tail-recursive Fib.

Finally, it was incredible that the goal of tail recursion optimization was achieved.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.