why memoizing is faster
Terry Reedy
tjreedy at udel.edu
Fri Mar 25 00:51:11 EDT 2011
On 3/24/2011 8:26 PM, Fons Adriaensen wrote:
> On Thu, Mar 24, 2011 at 08:12:22PM -0400, Terry Reedy wrote:
>
>> The irony of this is that memoizing 'recursive' functions with a
>> decorator depends on the fact the Python does not have truly recursive
>> functions. A function cannot call itself directly.
>
> I wonder what exactly is meant by that last sentence:
>
> * It doesn't happen (since the function name is evaluated
> to find the function to be called, as you explained).
In particular, the function name is resolved to an object when the
function is called and executed, rather than when the function is
compiled. To be more exact, I should have said, "A user-writen,
Python-coded function cannot call itself" This is assuming that we
exclude implementation-dependent hackery that subverts Python semantics
by exploiting implementation-specific information that is not part of
the language or its specification.
Consider
def f(): return f()
This books bad. Infinite recursion. Bad programmer...
Now continue with
f_orig=f
def f(): return 1
print(f_orig())
# 1
In context, f_orig is not recursive at all, in spite of its appearance.
Now consider this proposal: Introduce a keyword or special name, such as
'__func__', that means 'this function', to be resolved as such just
after compilation. With that, "def f: return __func__()" would be
directly recursive, and any wrapper would be ignored by the __func__() call.
Wrappers are not needed to memoize with recursion either:
def fib_recur(n, _cache = [1,1]):
if n >= len(_cache):
_cache.append(fib_recur(n-2) + fib_recur(n-1))
return _cache[n]
Perhaps prettier than fib_iter, posted before, but subject to external
rebinding and stack overflow.
Both fib_recur and fib_iter calculate fib(100) as 573147844013817084101
and fib(1000) as
70330367711422815821835254877183549770181269836358732742604905087154537118196933579742249494562611733487750449241765991088186363265450223647106012053374121273867339111198139373125598767690091902245245323403501
in a small fraction of a second.
--
Terry Jan Reedy
More information about the Python-list
mailing list