I've been playing around with memoization and recursion in python 3.3
Ignoring the fact that python is the wrong language to be doing this in, I've found that I get inconsistent results between using functools.lru_cache
to memoize, and not using functools.lru_cache
I'm not changing the recursion limit - it stays at the default, which for me is 1000.
To test the problem, I've written up a simple recursive function to sum numbers from 1 through i
#!/usr/bin/python
def sumtil(i):
"""Recursive function to sum all numbers from 1 through i"""
# Base case, the sum of all numbers from 1 through 1 is 1...
if i == 1:
return 1
else:
return i+sumtil(i-1)
# This will not throw an exception
sumtil(998)
# This will throw an exception
sumtil(999)
Running this function normally, I can run sumtil(998)
comfortably without hitting the recursion limit. sumtil(999)
or above will throw an exception.
However, if I try decorating this function with @functools.lru_cache()
, the recursion limit exception is thrown 3 times earlier, when running sumtil(333)
#!/usr/bin/python
import functools
@functools.lru_cache(maxsize=128)
def sumtil(i):
"""Recursive function to sum all numbers from 1 through i"""
# Base case, the sum of all numbers from 1 through 1 is 1...
if i == 1:
return 1
else:
return i+sumtil(i-1)
# This will not throw an exception
sumtil(332)
# This will throw an exception
sumtil(333)
Being that 332*3 = 996, but 333*3 = 999, it appears to me that the lru_cache decorator is causing each level of recursion in my function to become three levels of recursion.
Why do I get three times as many levels of recursion when using functools.lru_cache
to memoize a function?