... how frequently is the condition retested? Once every second?
Is is possible that having dozens of such tests all running at the same time could slow things down? Should I write my own loop that tests every 10 seconds instead?
I understand your rationale. I'm trying to come up with a counter-example, but cannot. However it should be possible to rewrite the macro to "trigger" once per second instead of pausing in some sort of loop. But even so, I doubt if that would make much difference.
It might be worth knowing how exactly the "Reduce CPU usage" works. I thought that I read a post which said that it "tapers off" execution after different durations (1 min, 5 min, etc.)
Before I posted earlier I searched for more info on that without success and then continued on the basis of what should be common sense. But I can't honestly say that @August's idea is without merit until he tries it
He should probably try it with a more computationally heavy operation than a simple math test, perhaps something like this:
And he would probably have to conduct this test over a long period of time, while logging the CPU usage over that time frame. Not easy. But he's an experimenter and a hard worker.
Nothing conclusive (of course, the way this test is set up), but the data seems to indicate that the Pause Until (with reduce CPU usage enabled) slows down evaluation frequency after about 10 seconds of reevaluating the conditions, and then again even more so after about a minute.
Thanks @tiffle, that's what I needed to know. I'll keep that setting on and not worry about it. I only expect to have at most a couple of dozen running at once, waiting for bootup processes to complete.
Test it and see? Maybe with Activity Monitor open as well?
Here's a macro that'll spawn 20 "Pause until..." macros that replicate yours, run the system_profiler shell command, kill all the "Pause until..." macros, run the shell command again. There's a "beep" halfway through if you want to check the KM menu bar item to see the pauses are running (before the beep) or cancelled (after).
So anything from 7 seconds (~15%) slower to > 1 second faster with pauses, suggesting that there's a small slow down but that other background activity is just as important. This is with "Reduce CPU Usage" off and the un-paused shell script done second so it would benefit from any cacheing, so the un-paused section has every advantage.
I suspect that you'll see even less impact in real world use, especially if this is for your startup macro where the pauses will impact CPU use but most of your macro's actions (launching apps) are I/O bound and any CPU use is probably on other cores anyway.
Nice to see all the tests on the "Reduce CPU Usage" in the Pause Action. I would love to see what this is actually doing documented in the Pause Action Wiki if that is possible. https://wiki.keyboardmaestro.com/action/Pause_Until
Why? Would it make a difference in how you write your macros? Do you need more than the "it checks rapidly at first, slows down after 10 seconds, slows a lot more after 60" that's on the Wiki page?
I suspect that the actual gap between checks will depend on a whole lot of stuff -- particularly the check itself. So this:
...takes a lot longer than this:
...for a single check.
Don't get me wrong, I love to dig into this stuff, but there's plenty on the Wiki already without including esoteric information that doesn't actually help.
Update: Completely missed that and just found it! "By default (v11.0+) Keyboard Maestro will start to conserve CPU usage of this action if it runs for a long time (after 10 seconds it will conserve a little, after 60 seconds it will conserve a lot) by only checking the condition periodically. You can turn off this feature in the action (gear) menu."
I guess what this is saying is it doesn't check as often. I have no idea how often it even checks in the first place but that is cool. I guess that's eneough info though I am still curious.
Read these first sentences... By default (v11.0+) Keyboard Maestro will start to conserve CPU usage of this action if it runs for a long time (after 10 seconds it will conserve a little, after 60 seconds it will conserve a lot) by only checking the condition periodically. You can turn off this feature in the action (gear) menu.
Then find out! Write yourself a macro that logs MILLISECONDS(), does a "Pause Until", logs MILLISECONDS() again, then finds the difference. That's how I know that the two pauses above have a huge difference in execution time, even when the condition is true before the action even starts.
Have some fun baselining how long a single, simple, action takes. On my machine that's ~2 milliseconds. If that's correct then the maximum rate of check is once every ~2ms, since you're effectively repeating the same action over and over again.
Now run 10 concurrent instances of the same speed-check macro. If your results are anything like mine then the Engine's CPU usage will increase 10-fold but the time taken doesn't change. So it isn't that "an action takes ~2ms", it's that "a macro is only revisited, and the next action executed, every ~2ms" -- plus, of course, the time it takes for the action to complete (unless it's async).
Now work out a way to log times with a pause that lasts for 10 (but less than 60) seconds. Do the same but >60s. Estimate how much throttling takes place. Wonder if a reduced rate of checking actually makes any difference at all to your real world use. And realise that, if it does, all you have to do is flick the switch on "Reduce CPU Usage" and spend CPU cycles to get increased reaction speed.
OK, here's a couple of demos. None of the results should be taken as absolutes, but will indicate the effect of "Reduce CPU Usage" as a "Pause Until" action's delay extends past 10, then 60, seconds.
"Image Detect Pause" is to demonstrate the impact on CPU usage, relies on an image that isn't on your screen, and the result will be more obvious the more screen real estate you have. Open Activity Monitor, filter on "Keyboard Maestro Engine", select the "CPU" pane, and set the "Update Frequency" (View menu) to "Very often (1 sec)".
Run the macro and watch the Engine's CPU usage over the first 10 second, after 10 seconds, and after 60 seconds. You'll have manually cancel the macro after that
"Master" is to demo how the frequency of checking changes. A simple "key down" check takes little CPU (as you'll see if you left Activity Monitor open) so the delay in reacting to the key being pressed will indicate how often the check is being made. "Master" spawns 3 async instances of "Pause Macro", each with their own pause before the "Pause Until" action, then simulates the key press 60 seconds later. Eventually it'll display the (approximate) delay in microseconds between the key being pressed and each macro responding to that.
Again, these numbers should be regarded as indicative rather than absolute. Every action takes time -- including the one that's getting the time! -- machine speeds vary, other things going on (particularly other macros) will have an impact. Run it a few times and you'll get some averages for your particular situation.
My results suggest that, on this 2020 iMac with 3.6GHz Intel i5, checking frequency is ~100/s at first, drops to ~20/s after 10s, and is only once every 3 seconds after a minute...
Oh wow and thank you. I did some tests after your first post and had typed a reply but I think I wanted to test one more thing before coming back. That is very cool what you put together and certainly taught me some things about Keyboard Maestro in how to run things. I am pretty slowly starting to get my head wrapped around more variables, and calulations using Keyboard Maestro. It's been exciting to learn new tricks. Thank you for sharing that and interesting results to wrap my head around.
Folks seem to have figured everything out already, but some comments.
Your action can only increase the CPU usage for the first 90 seconds after boot, so whatever CPU use it might use is going to be completely irrelevant long term.
Periodic triggers are much better than any pause action - Keyboard Maestro is designed to use virtually no CPU while no macros are running regardless of what triggers are active (and presuming the editor itself isn't asking for information). Once you are running a macro, the philosophy behind Keyboard Maestro is generally to get the thing you want done, done, not conserve CPU.
Your macro could, for example, be written with an Engine Launch or Login trigger that enables the macro, which has a periodic trigger (say 5 or 10 seconds), which checks the UPTIME function and if sufficient, does its thing and then disables the macro. This would be very efficient, but again, almost certainly pointless in this case.
A calculation like that shown would likely result in an imperceptible use of CPU more than just a Pause running. If the condition itself was expensive to calculate, that is what the Reduce CPU Usage is for, or alternatively you could so a sequence like:
While the condition remains untrue
Pause 5 seconds
Which is essentially what the Reduce CPU Usage option does, except you have no control on the pause length, and there are two values, one after 10 seconds, one after 60 seconds.
Oh cool that is very helpful. So I am guessing that it is even more than "while the condition remains untrue" because even that would have to keep checking if it was untrue if I understand right so "Reduce CPU Useage" just stops checking as often.
I love the explanation and thought behind how things are programmed in Keyboard Maestro. An amazing app to say the least. I spend hours in it everyday! What a blessing it is. So glad to have been forced to switch from QuicKeys.