I suspect that my “main” Tinderbox file has some agents or rules that are soaking up CPU time. I have seen some mentions of these issues in various places. For example, my understanding is that calculated display expressions are costly. Is there some general list somewhere? Alternatively, what would you nominate as your top 3 issues of this kind?
Get to know the Agents & Rules tab of the Tinderbox Inspector. If everything is cycling slowly, something is affecting performance.
My main tips:
- Cache Expressions (Display, Hover, etc.). IOW, calculate the expression and store it in a sting attribute (e.g $MyString) and then have the Expression attribute use the (now calculated) value in that string.
- Use prototypes, as they help with scoping queries (next item) even if nothing else.
- Scope your queries. Make each successive query term reduce the number of matches passed to the next term.
- Regex-type actions such a
.contains()are potentially the most intensive of operations , so in queries try and make them the last term.
- Don’t run all agents at full speed if you don’t need to - consider altering $AgentPriority.
- Don’t overlook edicts as a way to ensure thinks that need to run, but infrequently, can do so without clogging other more pressing tasks.
Great list! I think the contains() regex thing is most likely where I need to look. I was using this to pull text out of email messages and need to revisit.
Follow up question: I make heavy use of contains with regex in some agents. the contains is last in a set of conditions joined by the & operator. Does that mean that it only runs on those notes that return true for all the preceding conditions? If not, then perhaps I need to break this into two agents, the first to test all the lower cost conditions and the second to run on the results.
First, it’s often a mistake to worry too much about CPU-intensive code. For most people most of the time, the CPU cycles Tinderbox isn’t using aren’t used for anything else!
Two things might make one want to think about CPU.
First, if you rely on your battery a lot — for example, if you live on airplanes — then avoiding unnecessary work will save your battery.
Second, if you do something that requires a huge amount of computation, you might notice slow updates or other delays. That’s unusual, but it does happen.
One thing missing from Mark Anderson’s excellent list — and the most common culprit:
find(), collect(), and their kin have to look at every note in your document. contains() also has to look at every characters of every note — and if your regular expression is complicated, it may need to think hard each time.
Even these are seldom a problem! Cases where they might cause trouble arise when the computation is repeated very frequently. In particular
- DisplayExpression is evaluated whenever the display is updated. That’s a lot!
- Rules run frequently, too. Avoid repeating rules if you already have an answer; for example, if you’re using rules to extract addresses from the text of email messages, check first to see whether the rule has already done the work. If so, don’t do it again — or do it less often.
- Agent queries run less frequently, but examine every note. If the query has a clause like find() that also examines every note, then doubling the size of your document will quadruple the work the query has to do. Again, this seldom matters, but when it does, it’s usually easy to do part of the work less often.