Caching Nasal function calls
Jump to navigation
Jump to search
This article is a stub. You can help the wiki by expanding it. |
The FlightGear forum has a subforum related to: Nasal Scripting |
Nasal scripting |
---|
Nasal internals |
---|
Memory Management (GC) |
To cache expensive function calls, you can store their results in a lookup table and avoid repeated calling of the function if the value has already been computed - here's a very simple example, that isn't really heavy - just to illustrate the concept:
# Those subs should be "inline" for speed, but this is more readable
var Ysin = func (s) {
return math.sin(s*p)*150+y1; # currently 150 is + and - top value
};
var Ycos = func (s) {
return math.cos(s*p)*150+y1;
};
Next, introduce a cache class and a memoize class to create new cached functions:
var cache = {};
cache.new = func return { parents:[cache] };
var memoize = { callback:nil };
memoize.new = func(code) {
return { parents:[memoize], callback:code, cache:cache.new() };
}
memoize._save = func(value) me.cache[value] = me.callback(value);
memoize.lookup = func(value) {
var found = me.cache[value];
if (found) {
print("cached:",found,"\n");
return found;
}
print("not cached:");
return me._save(value);
}
var p = (2*math.pi)/360; # we don't want to calculate over and over.
var y1 = 151;
var Ycos = memoize.new( func (s) {
return math.cos(s*p)*150+y1;
} );
var Ysin = memoize.new( func (s) {
return math.sin(s*p)*150+y1;
} );
print( id(Ysin.cache) );
print("\n");
print( id(Ycos.cache) );
##
# test:
#
Ysin.lookup(3);
Ycos.lookup(3);
Ysin.lookup(4);
Ysin.lookup(3);
As a further step towards readability, make a function wrapper to remove the ".lookup" syntax:
var Ysinf = func(s) Ysin.lookup(s);
var Xsinf = func(s) Xsin.lookup(s);