Speak my name and I am summoned.
Uh, no real general recommendations. I think most of the slowdowns I’ve discovered have been due to the TADS3 VM’s list update speed. Not counting things like programming errors on my part, and things I’ve architected around because they’re obviously too slow (like floating point arithmetic).
I think the place you’re most likely to run into this without lists being immediately visible as the root cause is in movement: if you’re moving more than a couple hundred objects every turn you’ll start to notice slowdown, independent of the movement logic.
And I think I’ve commented on this previously, but I had written a bunch of automated rule evaluation logic that tried to “optimize” by adding or removing rules from a list to be evaluated each turn, in the theory that minimizing the number of items evaluated would improve performance. But updating lists was much slower than using an active
flag and checking it every turn, and as I recall the difference was more than an order of magnitude.
And I don’t know how useful this would be in your specific case, but what I’ve been doing is using a little timestamp object to do performance profiling in code I’m trying to streamline. This is the TS
class from the dataTypes
module, which works fine as a standalone thing, although you do need to #include
both <date.h>
and <bignum.h>
:
class TS: object
ts = nil
construct() { ts = new Date(); }
getInterval(d?) {
if((d == nil) || !d.ofKind(Date)) d = new Date();
return(((d - ts) * 86400).roundToDecimal(5));
}
;
Then on any builtin method that has a return value you can do something like:
modify someAdv3Object
someMethod([args]) {
local ts = new TS();
local r = inherited(args...);
_perf('someMethod()', ts.toInterval());
}
;
…and elsewhere something like…
#ifdef __DEBUG
_perf(lbl, t) { aioSay('\n<<lbl>> took <<toString(t)>> seconds.\n '); }
#else // __DEBUG
_perf(lbl, t) {}
#endif // __DEBUG
That’s composed-in-the-browser code so there might be typos, but hopefully it illustrates the idea.
This doesn’t work for some bits of the library that rely on exception handlers for flow control and a few things like that, but generally it seems to be a fairly reliable, if tedious, way to troubleshoot performance traps.