在Python中,我们将lru_cache
作为函数包装器。将它添加到您的函数中,每个不同的输入参数只会评估一次函数。
示例(来自Python文档):
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
我想知道 Matlab 中是否存在类似的东西?目前我正在使用缓存文件,如下所示:
function result = fib(n):
% FIB example like the Python example. Don't implement it like that!
cachefile = ['fib_', n, '.mat'];
try
load(cachefile);
catch e
if n < 2
result = n;
else
result = fib(n-1) + fib(n-2);
end
save(cachefile, 'result');
end
end
我这样做的问题是,如果我改变我的功能,我需要删除缓存文件。
有没有办法用Matlab实现这个,当我改变了函数并且缓存失效了?
答案 0 :(得分:2)
从matlab 2017开始,此功能可用: https://nl.mathworks.com/help/matlab/ref/memoizedfunction.html
a = memoized(@sin)
答案 1 :(得分:1)
我为自己的个人用途创造了类似的东西:CACHE课程。 (我还没有记录代码。)它似乎比Python的lru_cache
更灵活(我没有意识到,谢谢)因为它有几种方法可以准确调整缓存的内容(到节省内存)以及如何进行比较。它仍然可以使用一些改进(@ Daniel的建议使用containers.Map
类是一个很好的 - 虽然它会限制与旧的Matlab版本的兼容性)。代码在GitHub上,所以欢迎你分叉并改进它。
以下是如何使用它的基本示例:
function Output1 = CacheDemo(Input1,Input2)
persistent DEMO_CACHE
if isempty(DEMO_CACHE)
% Initialize cache object on first run
CACHE_SIZE = 10; % Number of input/output patterns to cache
DEMO_CACHE = CACHE(CACHE_SIZE,Input1,Input2);
CACHE_IDX = 1;
else
% Check if input pattern corresponds something stored in cache
% If not, return next available CACHE_IDX
CACHE_IDX = DEMO_CACHE.IN([],Input1,Input2);
if ~isempty(CACHE_IDX) && DEMO_CACHE.OUT(CACHE_IDX) > 0
[~,Output1] = DEMO_CACHE.OUT(CACHE_IDX);
return;
end
end
% Perform computation
Output1 = rand(Input1,Input2);
% Save output to cache CACHE_IDX
DEMO_CACHE.OUT(CACHE_IDX,Output1);
我创建了这个类来缓存耗时随机模拟的结果,并且在其他一些地方使用它后效果很好。如果有兴趣,我可能愿意花一些时间尽快记录代码而不是以后。如果有一种限制内存使用的方法(我自己的应用程序中的一个重要考虑因素)会很好,但获取任意Matlab数据类型的大小并非易事。我喜欢你对文件进行缓存的想法,这对于更大的数据来说可能是一个好主意。此外,创建一个执行Python lru_cache
所做的“精简”版本可能会很不错。