Poniżej jest pomysł dla klasy CacheableFunction
- Wydaje się wszystkie odpowiedzi do głównego pytania są skierowane w tym samym kierunku - trwałe Mapa jest drogą konsensusu do wyników cache, i zrobić to zbyt .
- Jeśli dane wejściowe są tablicami, należy je wprowadzić do łańcucha lub skalaru, który będzie używany jako klucz mapy. Istnieje wiele sposobów na mieszanie twoich 3 tablic wejściowych z kluczem, użyłem DataHash w moim poniższym rozwiązaniu.
- Zdecydowałem się uczynić z niego klasę, a nie funkcję taką jak memoize, aby wejściowa funkcja mieszająca mogła być dynamicznie określona jednorazowo, a nie na stałe.
- W zależności od formy wydruku używa również dzip/dunzip, aby zmniejszyć ślad zapisanych wyników.
- Potencjalne udoskonalenie: sprytny sposób decydowania, które elementy usunąć z trwałej mapy, gdy jej ślad pamięci osiąga pewien limit.
definicja klasy
classdef CacheableFunction < handle
properties
exeFun
hashFun
cacheMap
nOutputs
zipOutput
end
methods
function obj = CacheableFunction(exeFun, hashFun, nOutputs)
obj.exeFun = exeFun;
obj.hashFun = hashFun;
obj.cacheMap = containers.Map;
obj.nOutputs = nOutputs;
obj.zipOutput = [];
end
function [result] = evaluate(obj, varargin)
thisKey = obj.hashFun(varargin);
if isKey(obj.cacheMap, thisKey)
if obj.zipOutput
result = cellfun(@(x) dunzip(x), obj.cacheMap(thisKey), 'UniformOutput', false);
else
result = obj.cacheMap(thisKey);
end
else
[result{1:obj.nOutputs}] = obj.exeFun(varargin);
if isempty(obj.zipOutput)
obj.zipCheck(result);
end
if obj.zipOutput
obj.cacheMap(thisKey) = cellfun(@(x) dzip(x), result, 'UniformOutput', false);
else
obj.cacheMap(thisKey) = result;
end
end
end
function [] = zipCheck(obj,C)
obj.zipOutput = all(cellfun(@(x) isreal(x) & ~issparse(x) & any(strcmpi(class(x), ...
{'double','single','logical','char','int8','uint8',...
'int16','uint16','int32','uint32','int64','uint64'})), C));
end
end
end
Testowanie go ...
function [] = test_caching_perf()
A = CacheableFunction(@(x) long_annoying_function(x{:}), @(x) DataHash(x), 3);
B = rand(50, 50);
C = rand(50, 50);
D = rand(50, 50);
tic;
myOutput = A.evaluate(B, C, D);
toc
tic;
myOutput2 = A.evaluate(B, C, D);
toc
cellfun(@(x, y) all(x(:) == y(:)), myOutput, myOutput2)
end
function [A, B, C] = long_annoying_function(A, B, C)
for ii = 1:5000000
A = A+1;
B = B+2;
C = C+3;
end
end
a wyniki
>> test_caching_perf
Elapsed time is 16.781889 seconds.
Elapsed time is 0.011116 seconds.
ans =
1 1 1
zobaczyć http://stackoverflow.com/questions/9284130/caching-matlab-function-results-to-file – marsei
Widziałem, że (i zasugerował to w pytaniu), ale Problem polega na tym, że nie mogę znaleźć rozsądnego sposobu na spakowanie 3 argumentów wejściowych, aby pasował do tej klasy. –
jakiego typu są twoje trzy wejścia? czy to są skalary? wektor? matryce? jaki jest ich normalny zakres wartości? Ile wartości chcesz przechowywać w pamięci podręcznej? – Shai