1

So:

main does a loop, and every iteration it increments a tick by one

For example, say it were in python because that's easy to write:

def main():
    tick = 0
    while True:
        tick += 1

I want to trigger many different events every n-in-x ticks.


So I could skip nine-out-of-ten ticks using modulus:

if ticks % 10 == 0:
    act()

My worry is that doing a modulus operation is generally expensive in computing. (I'm guessing its expensive because colleges tell me division in general is expensive)

If I had, say a thousand [oh okay a hundred-billion] different cases, I wouldn't want to spend any excess time just qualifying tick cases.

But I also want each case to be ignorant of all the other cases.

So I'm curious what others may recommend as a super-efficient pass-n-out-of-x-ticks.

Note: Python is just for an example, I am not interested in python-only concepts.

  • 1
    Just use a counter, compare it it during the loop, execute when it reaches N ticks and then reset it. If you need to remain ignorant of this, then just write a class that can dispatch these, and dispatch all values. Nothing a little abstraction can't solve. – Vaughan Hilts Apr 6 '16 at 5:44
  • 1
    Modulus is one of the cheaper operations you can do on a computer, and even if it wasn't, it's an arithmetic operation; it's cost within the context of a loop like this is almost certainly going to be insignificant. If you're not sure, do some performance measurements, and remove all doubt. – Robert Harvey Apr 6 '16 at 5:55
  • 1
    Don't worry over it. Measure it and see if it's actually consuming a lot of time. – Blrfl Apr 6 '16 at 9:59
2

The simple solution to not using modulus is to maintain a tick-counter for each case and, when it triggers, reset it to 0.

An alternative is to keep the 'time' of the next trigger point, and increment this point when it is triggered. ie, if you want to fire every 10 ticks, compare the tick counter to 10, and when it fires, increment the trigger point variable to 20. This saves you having many counters that increment but at a cost of maintaining trigger values for each case.

Or you could have a single counter and a single trigger point that is re-calculated to reflect the next trigger time. ie if you have a trigger to fire every 10 ticks and another every 25 ticks, the trigger point would be changed to 10, 20, 25, 30 after each invocation. The cost here is passed to the time the trigger fires (which I assume is a reasonably lengthy operation itself)

(I've used these techniques myself, but usually for time-based delays where re-calculation of date/time values is more computationally intensive than an integer and the delay between ticks is relatively very long)

Now this may not be quicker than using modulus, the memory consumption might be enough to cause cache misses which is an order of magnitude greater than any FPU math operation. If you had many, many cases stored in an array then this is a likely outcome.

Of course, you might be able to use a better bit of maths to handle the modulus, and your CPU might be better or worse at calculating it. eg if your modulo value is a multiple of 2 you could use bit-shifting and masking to determine if a trigger point is reached, ie if you fire every 8 ticks, then the counter matches if the last 3 bits are 0 (ie 8 is 00001000, 16 is 00010000, 24 is 00011000 etc). Bit-masking is a very fast operation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.