HI all
I have 2 functions, say below:
func1[param1;param2]func2[param3;param4]
And now both need some kind of caching to speed it up. thus I having updating the naming of above to
func1Impl[param1;param2]func2Impl[param3;param4]
And for func1, it change to
func1:{[param1;param2] funcWithCache[param1;param2;"func1Impl[param1;param2]"]} ( similarly for func2 )
And having this for funcWithCache
funcWithCache:{[param1;param2;funcName] // check if cache exist cache upsert ([] key; eval parse funcName) // get from cache}
However, it saying that param1 not found when it trying to run eval parse funcName. Just wonder if there is solution about that or it is a limitation that we cannot do something like above?
Hi Carfield,
A possible solution to your problem looks something like this:
//generic cache
fcache:enlist[()]!enlist(::)
//caching funct_on decorator for dyadic functions_
cachedFunc2:{[c;f;p1;p2]r:c[p:(p1;p2)];if[not(::)~r;:r 0];@[c;p;:;enlist r:f[p1;p2]];r}
//your function, eg.
f:{` sv x,y}
// Now, you can use the projection cachedFunc2[`fcache;f] instead of f, like
cf:cachedFunc2[`fcache;f]
cf[a;b]
Regards,
András
Hi Carfield,
I think the problem you are having here boils down to the following issue.
When eval parse is used to evaluate the function the arguments needed are taken from
the root namespace rather than what is passed to the function.
a:1
b:2
f:{[x;y]0N!(x;y);a+b}
f[5;6]
5 6
3
eval parse "f[10;20]"
1 2
3
g:{[a;b] eval parse "f[a;b]"}[5;6]
1 2
Above, eval parse has searched for arguments a and b in the root namespace and
ignored the arguments 5 and 6 which we have intended to pass in.
The problem is therefore coming from the funcWithCache function where param1 and param2
are not more globally defined.
I also feel that the caching problem that you are having falls within the scope of
the TorQ finances starter pack and I will work to get an example of this for you.
Regards,
Brian
Hi Carfield,
I’ve looked at the cache.q script included in TorQ and found that there is a function there
that solves the problem you are having.
This function is called .cache.execute which takes two parameters,
the function you would like to execute and the maximum age of the result set you are willing to keep (i.e the result will be re-run if it is too old).
This cache.q script can be run as a standalone without the rest of TorQ as long as .proc.cp is first set to {.z.p}
Below is an example of how the function can be sped up on the second run.
q).proc.cp:{.z.p}q)f:{system"sleep 2";x+y} q)\ts f[2;3] 2009 752q)\ts .cache.execute["f[2;4]";0D01] 2012 1184q)\ts .cache.execute["f[2;4]";0D01] 0 800q)\ts .cache.execute[(f;4;5);0D01] 2010 1440q)\ts .cache.execute[(f;4;5);0D01] 0 1328
Below is documentation fo TorQ utilities where information on cache.q can be found
https://aquaqanalytics.github.io/TorQ/utilities/#cacheq
Below is the github repository for TorQ and the what is included in the cache.q script
https://github.com/AquaQAnalytics/TorQ
https://github.com/AquaQAnalytics/TorQ/blob/master/code/common/cache.q
Regards,
Brian