Cachetools module in Python

Cachetools is a Python module which provides various memoizing collections and decorators. It also includes variants from the functools’ @lru_cache decorator. To use it, first, we need to install it using pip.

pip install cachetools

Cachetools provides us five main function.

  • cached
  • LRUCache
  • TTLCache
  • LFUCache
  • RRCache

Let’s look at each of the following functions in detail and with examples.

Cached

cached is used as a decorator. When we call cache, it will cache the function for later use. This will by default perform a simple cache.

Syntax:



@cached(cache = {})
def some_fun():
    pass

Example: Let’s see it using an example. We are going to use the time module to see the efficiency of our module.

filter_none

edit
close

play_arrow

link
brightness_4
code

from cachetools import cached
import time
  
  
# Without cached
def fib(n):
    return n if n<2 else fib(n-1) + fib(n-2)
  
s = time.time()
print(old_fib(35))
print("Time Taken: ", time.time() - s)
  
# Now using cached
s = time.time()
  
# Use this decorator to enable caching
@cached(cache ={})
def fib(n):
    return n if n<2 else fib(n-1) + fib(n-2)
  
print(fib(35))
print("Time Taken(cached): ", time.time() - s)

chevron_right


Output:

9227465
Time Taken:  4.553245782852173
9227465
Time Taken(cached):  0.0003821849822998047

LRUCache

LRUCache is used inside the cached decorator. LRU cache means “Least Recently Used” cache. It takes a parameter “maxsize” which states that how recent functions should be cached.

Syntax:

@cached(cache= LRUCache(maxsize= 3))
def some_fun():
    pass

Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

from cachetools import cached, LRUCache
import time
  
  
# cache using LRUCache
@cached(cache = LRUCache(maxsize = 3))
def myfun(n):
      
    # This delay resembles some task
    s = time.time()
    time.sleep(n)
    print("\nTime Taken: ", time.time() - s)
    return (f"I am executed: {n}")
  
  
# Takes 3 seconds
print(myfun(3))
  
# Takes no time
print(myfun(3))
  
# Takes 2 seconds
print(myfun(2))
  
# Takes 1 second
print(myfun(1))
  
# Takes 4 seconds
print(myfun(4))
  
# Takes no time
print(myfun(1))
  
# Takes 3 seconds because maxsize = 3 
# and the 3 recent used functions had 1,
# 2 and 4.
print(myfun(3))

chevron_right


Output:

Time Taken:  3.0030977725982666
I am executed: 3
I am executed: 3

Time Taken:  2.002072334289551
I am executed: 2

Time Taken:  1.001115083694458
I am executed: 1

Time Taken:  4.001702070236206
I am executed: 4
I am executed: 1

Time Taken:  3.0030171871185303
I am executed: 3

Note: LRUCache can also be called from the standard Python package – functools. It can see imported as

from functools import lru_cache
@lru_cache
def myfunc():
    pass

TTLCache

TTLCache or “Time To Live” cache is the third function that is included in cachetools module. It takes two parameters – “maxsize” and “TTL”. The use of “maxsize” is the same as LRUCache but here the value of “TTL” states for how long the cache should be stored. The value is in seconds.



Syntax:

@cached(cache= TTLCache(maxsize= 33, ttl = 600))
def some_fun():
    pass

Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

from cachetools import cached, TTLCache
import time
  
# Here recent 32 functions 
# will we stored for 1 minutes
@cached(cache = TTLCache(maxsize = 32, ttl = 60))        
def myfun(n):
      
    # This delay resembles some task
    s = time.time()
    time.sleep(n)
    print("\nTime Taken: ", time.time() - s)
    return (f"I am executed: {n}")
  
print(myfun(3))
print(myfun(3))
time.sleep(61)
print(myfun(3))

chevron_right


Output:

Time Taken:  3.0031025409698486
I am executed: 3
I am executed: 3

Time Taken:  3.0029332637786865
I am executed: 3

LFUCache

LFUCache or “Least Frequently Used” cache is another type of caching technique that retrieves how often an item is called. It discards the items which are called least often to make space when necessary. It takes one parameter – “maxsize” which is the same as in LRUCache.

Syntax:

@cached(cache= LFUCache(maxsize= 33))
def some_fun():
    pass

Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

from cachetools import cached, LFUCache
import time
  
# Here if a particular item is not called 
# within 5 successive call of the function,
# it will be discarded
@cached(cache = LFUCache(maxsize = 5))
def myfun(n):
      
    # This delay resembles some task
    s = time.time()
    time.sleep(n)
    print("\nTime Taken: ", time.time() - s)
    return (f"I am executed: {n}")
  
print(myfun(3))
print(myfun(3))
print(myfun(2))
print(myfun(4))
print(myfun(1))
print(myfun(1))
print(myfun(3))
print(myfun(3))
print(myfun(4))

chevron_right


Output:


Time Taken:  3.002413272857666
I am executed: 3
I am executed: 3

Time Taken:  2.002107620239258
I am executed: 2

Time Taken:  4.003819465637207
I am executed: 4

Time Taken:  1.0010886192321777
I am executed: 1
I am executed: 1
I am executed: 3
I am executed: 3
I am executed: 4

RRCache

RRCache or “Random Replacement” cache is another type of caching technique that randomly chooses items in the cache and discards them to free up space when necessary. It takes one parameter – “maxsize” which is the same as in LRUCache. It also has a parameter choice which is by default set to “random.choice”.

Syntax:

@cached(cache= RRCache(maxsize= 33))
def some_fun():
    pass

Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

from cachetools import cached, RRCache
import time
  
# Here if a particular item is not called
# within 5 successive call of the function,
# it will be discarded
@cached(cache = RRCache(maxsize = 5))
def myfun(n):
      
    # This delay resembles some task
    s = time.time()
    time.sleep(n)
    print("\nTime Taken: ", time.time() - s)
    return (f"I am executed: {n}")
  
print(myfun(3))
print(myfun(3))
print(myfun(2))
print(myfun(4))
print(myfun(1))
print(myfun(1))
print(myfun(3))
print(myfun(2))
print(myfun(3))

chevron_right


Output:

Time Taken:  3.003124713897705
I am executed: 3
I am executed: 3

Time Taken:  2.0021231174468994
I am executed: 2

Time Taken:  4.004120588302612
I am executed: 4

Time Taken:  1.0011250972747803
I am executed: 1
I am executed: 1
I am executed: 3
I am executed: 2
I am executed: 3



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.