Clear LRU Cache in Python


In this article, we will learn how to clear an LRU cache implemented in Python. Before we dive deep into the coding aspect, let's explore a little about what an LRU cache is and why it is popular.

LRU Cache, also known as the Least Recently Used Cache, is a data structure that is widely used in computer science to improve the performance of applications by reducing the time it takes to access frequently−used data. The LRU Cache stores a limited number of items and removes the least recently used item when the cache becomes full. This allows the most frequently−used items to remain in the cache and be accessed quickly, while less frequently−used items are removed to make space for new items.

The LRU Cache is particularly useful in applications where there is a high cost associated with retrieving data, such as disk I/O or network access. In these cases, caching frequently−used data in memory can significantly improve the application's performance by reducing the number of expensive operations required to retrieve the data.

The LRU Cache is used in a wide variety of applications, including databases, web servers, compilers, and operating systems. It is particularly useful in applications that require frequent access to a large amount of data, such as search engines and data analytics platforms.

Interacting with LRU cache in Python

In Python 3.2 and above, the functools module includes a powerful feature that allows programmers to interact with the LRU Cache. This feature can be utilized by using a decorator that is placed above a class or function definition. By applying this decorator to functions that require frequent variable access and changes, the performance of the function can be significantly improved.

When working with functions that require the processing of large amounts of data or complex computations, the use of an LRU Cache can greatly speed up the execution time. This is because the LRU Cache stores frequently−used data in memory, allowing the function to quickly access and process the data without incurring the cost of time−consuming I/O operations.

By utilizing the LRU Cache, Python programmers can reduce the execution time of their applications and improve their performance. This is particularly important when working with large−scale applications or those that require real−time data processing, where even small improvements in performance can result in significant gains.

In summary, the functools module in Python provides a powerful mechanism for interacting with the LRU Cache. By using the LRU Cache, programmers can improve the performance of their applications by reducing the time required for expensive variable access and change operations. The use of the LRU Cache is particularly beneficial in applications that require real−time data processing or work with large amounts of data.

Now that we know a little about LRU cache, let's make use of it in Python.

The cache clear() method of the functools module in Python can be used to clear an LRU (Least Recently Used) cache.

The cache is fully cleared using this technique.

Sample Code Snippet

from functools import lru_cache

@lru_cache(maxsize=128)
def some_function(arg):
	# function implementation
	return result

# clear the cache
some_function.cache_clear()

Explanation

In the above example, some_function is decorated with lru_cache, which creates an LRU cache with a maximum size of 128. To clear the cache, you can call the cache_clear() method on the function object, which will remove all the entries from the cache.

Note that calling cache_clear() will clear the cache for all arguments. If you want to clear the cache for a specific set of arguments, you can use a different cache implementation, such as functools.typed_lru_cache, which allows you to clear the cache for a specific argument using the cache_clear() method with an argument.

Now let's make use of the above code, and write a working example.

Consider the code shown below.

Example

from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n):
	"""Return the nth Fibonacci number."""
	if n < 2:
    	return n
	return fibonacci(n-1) + fibonacci(n-2)

# Call the function with some arguments to populate the cache
print(fibonacci(10))  # Output: 55
print(fibonacci(15))  # Output: 610

# Clear the cache
fibonacci.cache_clear()

# Call the function again to see that it's recomputed
print(fibonacci(10))  # Output: 55

Explanation

In this example, the fibonacci function uses lru_cache to memoize its results. The cache has a maximum size of 128, so the function will remember the results of the most recent 128 calls.

We first call the function with some arguments to populate the cache. Then, we clear the cache using the cache_clear() method. Finally, we call the function again with the same argument to see that it's recomputed instead of using the cached result.

To run the above code, we need to run the command shown below.

Command

python3 main.py

Once we run the above command, we should expect the output similar to the one shown below.

Output

55
610
55

If we want, we can also print the current state information of the cache as well in the above code, to do that we need to make use of the cache_info() method.

Consider the updated code shown below.

Example

from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n):
	"""Return the nth Fibonacci number."""
	if n < 2:
    	return n
	return fibonacci(n-1) + fibonacci(n-2)

# Call the function with some arguments to populate the cache
print(fibonacci(10))  # Output: 55
print(fibonacci(15))  # Output: 610

print(fibonacci.cache_info())

# Clear the cache
fibonacci.cache_clear()

# Call the function again to see that it's recomputed
print(fibonacci(10))  # Output: 55

print(fibonacci.cache_info())

Explanation

The @lru cache decorator in the code above accepts the optional argument maxsize, which designates the cache's utmost size.

The cache size is limitless if maxsize is not defined.

The least recently used items are removed if the cache fills up to allow room for new ones.

The function object itself houses the cache that @lru cache uses.

Accordingly, the cache is private to the function and is not shared by other versions of the function. Also, the different part here is the cache_info() method, which is used to print information about the LRU cache used by the fibonacci function. This includes the number of cache hits and misses, as well as the size of the cache.

To run the above code, we need to run the command shown below.

Command

python3 main.py

Once we run the above command, we should expect the output similar to the one shown below.

Output

55
610
CacheInfo(hits=14, misses=16, maxsize=128, currsize=16)
55
CacheInfo(hits=8, misses=11, maxsize=128, currsize=11)

Now that we have seen how we can clear the cache, let's make use of it in another example.

Consider the code shown below.

Example

from functools import lru_cache

@lru_cache(maxsize=128)
def edit_distance(s1, s2):
	"""
	Compute the edit distance between two strings using dynamic programming.
	"""
	if not s1:
    	return len(s2)
	elif not s2:
    	return len(s1)
	elif s1[0] == s2[0]:
    	return edit_distance(s1[1:], s2[1:])
	else:
    	d1 = edit_distance(s1[1:], s2) + 1  # deletion
    	d2 = edit_distance(s1, s2[1:]) + 1  # insertion
    	d3 = edit_distance(s1[1:], s2[1:]) + 1  # substitution
    	return min(d1, d2, d3)

# Call the function with some arguments to populate the cache
print(edit_distance("kitten", "sitting"))  # Output: 3
print(edit_distance("abcde", "vwxyz"))	# Output: 5

# Clear the cache
edit_distance.cache_clear()

# Call the function again to see that it's recomputed
print(edit_distance("kitten", "sitting"))  # Output: 3

Explanation

In this example, the edit_distance function computes the edit distance between two strings using dynamic programming. The function is recursive and has three base cases: if one of the strings is empty, the edit distance is the length of the other string; if the first characters of the two strings are the same, the edit distance is the edit distance between the rest of the strings; otherwise, the edit distance is the minimum of the edit distances for the three possible operations: deletion, insertion, and substitution.

To improve the performance of the function, we use lru_cache to memoize its results. The cache has a maximum size of 128, so the function will remember the results of the most recent 128 calls. This allows us to avoid recomputing the edit distance for the same arguments.

We first call the function with some arguments to populate the cache. Then, we clear the cache using the cache_clear() method. Finally, we call the function again with the same argument to see that it's recomputed instead of using the cached result.

Note that the edit_distance function is just an example, and there are more efficient ways to compute the edit distance between two strings (e.g., using the Wagner−Fischer algorithm). The purpose of this example is to demonstrate how to use lru_cache to memoize the results of a recursive function.

Conclusion

In conclusion, clearing the LRU (Least Recently Used) cache in Python can be important in certain situations to manage memory and ensure that the cache remains up−to−date. The LRU cache is a built−in caching mechanism provided by Python's functools module, which can be used to cache the results of a function based on its arguments. The @lru_cache decorator is used to enable caching for a function, and maxsize can be specified to set a limit on the cache size.

The decorated function object's cache clear() method can be used to clear the LRU cache. By clearing out all cached results, this technique makes the cache recent while freeing up memory. If the function is updated or if the input data changes frequently, it might be essential to clear the cache.

Overall, the LRU cache provides a simple yet effective way to improve the performance of Python functions, especially those that are computationally intensive or called with the same arguments multiple times. Clearing the cache when necessary can help maintain the performance gains achieved through caching and ensure that the cache remains effective in reducing computation time.

Updated on: 02-Aug-2023

4K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements