Remove the lfu_cache. Add more tests.

This commit is contained in:
Raymond Hettinger 2010-08-15 03:30:45 +00:00
parent 0f56e90f05
commit f309828175
3 changed files with 29 additions and 129 deletions

View file

@ -66,45 +66,32 @@ Some smaller changes made to the core Python language are:
New, Improved, and Deprecated Modules
=====================================
* The functools module now includes two new decorators for caching function
calls, :func:`functools.lru_cache` and :func:`functools.lfu_cache`. These can
save repeated queries to an external resource whenever the results are
expected to be the same.
* The functools module now includes a new decorator for caching function calls.
:func:`functools.lru_cache` can save repeated queries to an external resource
whenever the results are expected to be the same.
For example, adding a caching decorator to a database query function can save
database accesses for popular searches::
@functools.lfu_cache(maxsize=50)
@functools.lru_cache(maxsize=300)
def get_phone_number(name):
c = conn.cursor()
c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,))
return c.fetchone()[0]
The caches support two strategies for limiting their size to *maxsize*. The
LFU (least-frequently-used) cache works bests when popular queries remain the
same over time. In contrast, the LRU (least-recently-used) cache works best
query popularity changes over time (for example, the most popular news
articles change each day as newer articles are added).
To help with choosing an effective cache size, the wrapped function is
instrumented with two attributes *hits* and *misses*::
The two caching decorators can be composed (nested) to handle hybrid cases.
For example, music searches can reflect both long-term patterns (popular
classics) and short-term trends (new releases)::
@functools.lfu_cache(maxsize=500)
@functools.lru_cache(maxsize=100)
def find_lyrics(song):
query = 'http://www.example.com/songlist/%s' % urllib.quote(song)
page = urllib.urlopen(query).read()
return parse_lyrics(page)
To help with choosing an effective cache size, the wrapped function
is instrumented with two attributes *hits* and *misses*::
>>> for song in user_requests:
... find_lyrics(song)
>>> print(find_lyrics.hits, find_lyrics.misses)
>>> for name in user_requests:
... get_phone_number(name)
>>> print(get_phone_number.hits, get_phone_number.misses)
4805 980
If the phonelist table gets updated, the outdated contents of the cache can be
cleared with::
>>> get_phone_number.clear()
(Contributed by Raymond Hettinger)
* The previously deprecated :func:`contextlib.nested` function has been