Skip to content

Instantly share code, notes, and snippets.

@Argysh
Forked from Susensio/numpy_lru_cache.md
Last active July 22, 2019 15:26
Show Gist options
  • Save Argysh/380e516e1b166a406be3da589f13d6a2 to your computer and use it in GitHub Desktop.
Save Argysh/380e516e1b166a406be3da589f13d6a2 to your computer and use it in GitHub Desktop.
Make function of numpy array cacheable

caching functions and methods with a numpy array as first argument

from copy import copy
from time import sleep

array = np.random.rand(900,600)
param = int(np.random.rand()*1000)

print('\nwith @npCache:')
@vocalTimeit()
@npCache()
def doSomething(array, param):
    print("Calculating...")
    sleep(1)
    return True

for i in range(5):
    res = copy(doSomething(array, param))

class DummyClass():
    def __init__(self):
        for i in range(5):
            res = copy(self.doSomethingMethod(array, param))
    @vocalTimeit()
    @npCacheMethod()
    def doSomethingMethod(self, array, param):
        print("Calculating...")
        sleep(1)
        return True
    
print('\nwith @npCacheMethod')
dummyClass = DummyClass()
with @npCache:
Calculating...
doSomething execution time: 1.073955507017672 s
doSomething execution time: 0.0814172513782978 s
doSomething execution time: 0.08347152546048164 s
doSomething execution time: 0.08153043873608112 s
doSomething execution time: 0.08101261034607887 s

with @npCacheMethod
Calculating...
doSomethingMethod execution time: 1.075349354185164 s
doSomethingMethod execution time: 0.08380787633359432 s
doSomethingMethod execution time: 0.08389369770884514 s
doSomethingMethod execution time: 0.0843976391479373 s
doSomethingMethod execution time: 0.0834763403981924 s
import numpy as np
from functools import lru_cache, wraps
from timeit import default_timer
def vocalTimeit(*args, **kwargs):
''' provides the decorator @vocalTime which will print the name of the function as well as the
execution time in seconds '''
def decorator(function):
@wraps(function)
def wrapper(*args, **kwargs):
start = default_timer()
results = function(*args, **kwargs)
end = default_timer()
print('{} execution time: {} s'.format(function.__name__, end-start))
return results
return wrapper
return decorator
def npCache(*args, **kwargs):
''' LRU cache implementation for functions whose FIRST parameter is a numpy array
forked from: https://gist.github.com/Susensio/61f4fee01150caaac1e10fc5f005eb75 '''
def decorator(function):
@wraps(function)
def wrapper(np_array, *args, **kwargs):
hashable_array = tuple(map(tuple, np_array))
return cached_wrapper(hashable_array, *args, **kwargs)
@lru_cache(*args, **kwargs)
def cached_wrapper(hashable_array, *args, **kwargs):
array = np.array(hashable_array)
return function(array, *args, **kwargs)
# copy lru_cache attributes over too
wrapper.cache_info = cached_wrapper.cache_info
wrapper.cache_clear = cached_wrapper.cache_clear
return wrapper
return decorator
def npCacheMethod(*args, **kwargs):
''' LRU cache implementation for methods whose FIRST parameter is a numpy array
modified from: https://gist.github.com/Susensio/61f4fee01150caaac1e10fc5f005eb75 '''
def decorator(function):
@wraps(function)
def wrapper(s, np_array, *args, **kwargs):
hashable_array = tuple(map(tuple, np_array))
return cached_wrapper(s, hashable_array, *args, **kwargs)
@lru_cache(*args, **kwargs)
def cached_wrapper(s, hashable_array, *args, **kwargs):
array = np.array(hashable_array)
return function(s, array, *args, **kwargs)
# copy lru_cache attributes over too
wrapper.cache_info = cached_wrapper.cache_info
wrapper.cache_clear = cached_wrapper.cache_clear
return wrapper
return decorator
if __name__ == "__main__":
from copy import copy
from time import sleep
array = np.random.rand(900,600)
param = int(np.random.rand()*1000)
print('\nwith @npCache:')
@vocalTimeit()
@npCache()
def doSomething(array, param):
print("Calculating...")
sleep(1)
return True
for i in range(5):
res = copy(doSomething(array, param))
print('\nwith @npCacheMethod')
class DummyClass():
def __init__(self):
for i in range(5):
res = copy(self.doSomethingMethod(array, param))
@vocalTimeit()
@npCacheMethod()
def doSomethingMethod(self, array, param):
print("Calculating...")
sleep(1)
return True
dummyClass = DummyClass()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment