Created
July 5, 2012 14:26
-
-
Save kamiller/3053977 to your computer and use it in GitHub Desktop.
python LRU functools wrapper impl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import collections | |
import functools | |
def lru_cache(maxsize=100): | |
'''Least-recently-used cache decorator. | |
Arguments to the cached function must be hashable. | |
Cache performance statistics stored in f.hits and f.misses. | |
http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used | |
''' | |
def decorating_function(user_function): | |
cache = collections.OrderedDict() # order: least recent to most recent | |
@functools.wraps(user_function) | |
def wrapper(*args, **kwds): | |
key = args | |
if kwds: | |
key += tuple(sorted(kwds.items())) | |
try: | |
result = cache.pop(key) | |
wrapper.hits += 1 | |
except KeyError: | |
result = user_function(*args, **kwds) | |
wrapper.misses += 1 | |
if len(cache) >= maxsize: | |
cache.popitem(0) # purge least recently used cache entry | |
cache[key] = result # record recent use of this key | |
return result | |
wrapper.hits = wrapper.misses = 0 | |
return wrapper | |
return decorating_function | |
if __name__ == '__main__': | |
@lru_cache(maxsize=20) | |
def f(x, y): | |
return 3*x+y | |
domain = range(5) | |
from random import choice | |
results = set() | |
for i in range(1000): | |
r = f(choice(domain), choice(domain)) | |
results.add(r) | |
for r in results: | |
print r | |
print "total: "+repr((f.hits, f.misses)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment