Straight logic trumps "is in" list (which is really an OR statement)

Testing that a variable c is in a list {a, b} is equivalent to OR-ing the items in the list with the variable: c = a OR c = b. Similarly, if a variable is not in a list {A, B} that is equivalent to AND-ing the negatives: C ≠A AND C ≠B.

A finite state machine is a system that can only follow certain paths to attain a fixed number of operating conditions set by its inputs and its current condition (think of that as the context for the input(s)). Programming the controller for such a system is inevitably a giant case statement, or in AppleScript an if, else if, etc. string of conditions) that amount to a bunch of ORs and ANDs that set up the conditions for the transition to a new state.

An example of one of many lines might be “if p = 2 or p = 5 or p = 7 or p > 8 and q = 3 then set r to 2”. I thought it might be easier to set these up instead in this form: “if p is in {2, 5, 7} or p > 8 and q = 3 then set r to 2”, or even “if p is in {2, 5, 7, 9, 10, 11, 12) and q = 3 then…” but it ain’t so. The straight logic all strung out runs faster. Interesting, I thought.

“You’s crazy Alfalfa” - Buckwheat

The accuracy of controllers of this type depends on how often they “look”, i.e. how often they can service the logic and get back to the inputs. Sometimes they’re clocked, but are often asynchronous. Optimizing the script so I can do this with an old Mac is my objective.

Many others, starting with my wife, might agree with you (and The Little Rascals a.k.a. Our Gang) though.

Hi, Adam. The list method can be more convenient to code, but as you say, a string of individual comparisons is usually faster. When the list is written literally in the ‘is in’ instruction, it’s created in its entirety every time the instruction’s carried out. A series of simple integer tests, on the other hand, doesn’t take so long to set up. Moreover, with OR, the tests stop when there’s a hit. So if p turns out to be equal to 2, the running script doesn’t bother with the 5, 7, 9, etc. Obviously, testing that a number is simply greater than 8 takes less time than comparing it with a series of values in a list.

If you’re using the list method and there are a number of ‘is in’ comparisons with the same list during the run of the script, you can speed things up by assigning the list to a variable beforehand and using the variable instead of the literal in the numerous comparisons. That way, the list is only created once.

Because of operator precedence, the last version doesn’t have the same logic. The respective equivalents are:

p = 2 or p = 5 or p = 7 or (p > 8 and q = 3)

(p is in {2, 5, 7}) or (p > 8 and q = 3)

(p is in {2, 5, 7, 9, 10, 11, 12}) and q = 3

Thank you Nigel - hadn’t thought to consider operator precedence - have already converted everything to “raw” logic, i.e., pure OR and AND statements which are quite brisk. When all is said and done, this will run on an ancient SE/30 (doing nothing else) using its printer port as an RS232 interface to some binary inputs (open/closed contacts) and binary outputs (opto-isolated relays). There’s a long way to go yet and it’s stricktly a “hackers” project. I did have the SE/30 set up as a router for a while, but it’s been idle for too long now (it was too slow to keep up with 10base-T).