Keep a 16 program cache for ircbotRun()

This commit is contained in:
Juhani Krekelä 2018-05-26 23:27:47 +03:00
parent 713ded5adb
commit 991136e703
2 changed files with 55 additions and 2 deletions

View File

@ -23,7 +23,6 @@ TODO
### gir.js
* Make VM and transformMultiplyLoops use a Proxied object that gives out 0
for nonexistent elements for tape and allows using [] interface
* Keep a cache of compiled programs in `ircbotRun()`
* Support for other types of EOF?
### gir.html

56
gir.js
View File

@ -928,10 +928,64 @@ function compile(program, enableExtensions = true) {
return optimize(parse(program, enableExtensions));
}
const programCacheSize = 16;
// string → {compiled: [flatCommandObjects], extensions: bool}
let programCache = new Map();
// (string, bool) → [flatCommandObjects]
function cachedCompile(program, enableExtensions = true) {
function compileToCache() {
console.log('compile'); //debg
// Are we already in the cache? If yes, drop the old one,
// since something must have been changed if we're called
if(programCache.has(program)) {
programCache.delete(program);
}
let compiled = compile(program, enableExtensions);
programCache.set(program, {compiled: compiled,
extensions: enableExtensions});
// Are we over the cache size? If yes, drop the least
// recently added
if(programCache.size > programCacheSize) {
console.log('delete');
// .keys() gives them in insertion order. Since
// there isn't a nice way to extract a thing out
// of an iterator, use a for loop and break out
// after first round
for(let leastRecentlyUsed of programCache.keys()) {
programCache.delete(leastRecentlyUsed);
break;
}
}
}
if(programCache.has(program)) {
// There is a compiled version of this program
let {compiled, extensions} = programCache.get(program);
// If extensions enabled state is the same as ours, we can
// just update the useOrder and return this
// If not, we need to compile a new program
if(extensions == enableExtensions) {
return compiled;
} else {
compileToCache();
let {compiled} = programCache.get(program);
return compiled;
}
} else {
compileToCache();
let {compiled} = programCache.get(program);
return compiled;
}
}
// (string, string, int) → string
function ircbotRun(program, input, maxCycles = 400000) {
// TODO; Cache programs
let compiled = compile(program);
let compiled = cachedCompile(program);
let vm = newVM(compiled, encodeUTF8(input));
let result = runVM(vm, maxCycles);