|
3
|
A new tail recursion decorator that eliminates tail calls for recursive functions is introduced.
It is about 2 months ago that Crutcher Dunnavant published a cute tail recursion decorator that eliminates tail calls for recursive functions in Python i.e. turning recursion into iteration [1]. The new one gets rid of catching exceptions and is faster. The source code shows two versions. The first one uses stack frame inspections just like Crutchers decorator, the second one abandones those and runs twice as fast. [1] http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/474088 Warning: the optimization comes at its price. The dumbed down lookup procedure causes brittleness in certain cases and different @tail_recursion decorators can interfere as in the following counter example: @tail_recursion def even(n): if n == 0: return True else: return odd(n-1) @tail_recursion def odd(n): if n == 0: return False else: return even(n-1) Commenting out one of these decorators let it work again. Crutchers decorator works in both cases and shows the expected bounded sized stack behaviour. Note also that these decorators are not optimizing and for small argument values they are actually far slower.
Tags: algorithms
|
3 comments
Add a comment
Sign in to comment
Download
Copy to clipboard

This decorator is a bit fragile. You need to add some error handling to the code. If a call to the decorated function ever raises an exception then all subsequent calls to the function will return garbage. e.g.
This version is more robust against exceptions.
In Michele's version, CONTINUE should be an instance attribute, not a class attribute, to work for mutually recursive functions (like even/odd). Also __call__ can be simplified a bit:
As Kay noted, the decorator is beneficial only for large values; on my box (T60, WinXP, Python 2.5), the undecorated factorial is faster for up to N~=1700 (after increasing the default recursion limit).