Request: Improve Performance of Executing AppleScript Compiled Files

Peter, you do NOT need to cache compiled AppleScripts. You just need to run the compiled script file like FastScripts does. The developer of FastScripts is very friendly and helpful, and I'm sure he'd be glad to share with you his technique.

I presume FastSpring runs the scripts directly with the AppleScript subsystem, but the AppleScript subsystem has a tendency to crash, so Keyboard Maestro runs all AppleScripts via the osascript sub-process. Doing otherwise in the past led to crashes which take out the engine.

No, it uses its own system for running script files. But when it comes to that, I prefer Apple’s system because FastScript’s runner has two issues:

(BTW, the progress indicator is also missing when running script files with KM.)

You keep repeating that, but neither I, nor Chris @ccstone, have observed that to be the case. Do you have any recent, actual data that shows how often AppleScript crashes?

Maybe you had a bad experience long ago that is still giving you this opinion.

If you are referring to the native AppleScript progress indicator, it is not really useful unless you create an App.

For a much better progress indicator, see:
SKProgressBar by StefanK

Are you referring to tracking of AppleScript Properties?
With KM, I find that I much prefer using KM Global Variables to maintain data across AppleScript executions.
How often you you really use AppleScript Properties to maintain changes in data between executions?

And I really do NOT like the fact that every time I run a script file via KM it updates the file modification date. So you can't tell from the Finder when a script was last updated.

It may no longer be an issue, maybe Apple have fixed any crashes. Although that is very hard to believe given the age of the code base and the likelihood that Apple would touch anything in it if it did not absolutely have to.

But there is no way for me to determine this except by changing it and then watching for crashes, which is not something I’d like to try.

There have definitely been changes that could affect, and reduce, AppleScript crashes:

  1. the macOS has obviously changed many times
  2. AppleScript has had a number of significant changes over the years.

Whether or not Apple made a specific change to fix a bug, or it just got fixed as part of other changes, we'll never know, because for one thing. we don't have reproducible steps that causes a crash.

I can only tell you that Chris @ccstone and I have discussed this at length, and both of us have been active in the AppleScript community, and I honestly have never heard of AppleScript crashes, UNLESS the script is very long (thousands of lines) and approaching the limits of the AppleScript compiler.
Personally, I have never had an AppleScript that crashed the AppleScript engine.

So, why don't do this if it does not require an excessive amount of work on your part: Create a KM beta that uses the FastScripts technique (or other technique if you feel it is better), and let those of us in the KM Beta group try to crash it.

1 Like

This would not come anywhere close to being a sufficient test. The crashes that happened were likely related to specific applications and/or specific extensions and/or specific usage cases and/or random memory corruptions.

The beta testers could hammer on it for weeks and it would prove next to nothing about the likelihood that there are undetected crashes.

My goal with Keyboard Maestro is always to have zero crashes. This is above pretty much every other goal.

I will look at how feasible it is to allow a hidden preference to choose an alternative AppleScript method. To this end, if anyone has a specific AppleScript that shows the difference in performance, and/or knows specifically how to run the AppleScript faster, let me know.

1 Like

When AppleScript crashes as used with KM, does KM log that crash, and do you get any type of notification about it.? I would think it would be best if you started a log of crashes so none of us are just guessing. Obviously, this would also give us more insight into the cause of, and frequency of, the crashes.

It just occurred to me that AppleScript is, at least as far as I recall, not thread-able, so while the script was running, the engine would be locked up, which makes running the AppleScript within the Keyboard Maestro Engine impractical in any event.

Could you run it out-of-process with a helper that uses non-locking IAC?

If I ran it out of process, I'm not sure how that would be any difference to running it using osascript…?

Do people have specific scripts that result in significantly different performance? I just assuming AppleScript is relatively slow, and typically doing a bunch of cross-application communication, but I can't remember ever thinking “gee, I really need this AppleScript to run faster”, so some actual real world cases might be helpful. Although we have wandered far off the original topic.

1 Like

Well yes, AppleScript has always been cludgy and slow in any context where you want fairly fast execution. The thread was originally about improving Swift performance by caching compiled binaries of Swift scripts.

1 Like

I'm not sure if this will be a convincing example, but I have a set of simple AppleScripts I use to control the position of the picture-in-picture window that run noticeably slower when executed via KM than FastScripts. It's admittedly not a huge difference—probably no more than half a second delay—but when trying both methods, FastScripts feels instantaneous and KM…doesn't. Here are the script files and macros (which just execute the script files) I use if you'd like to try yourself:

PiP (16.8 KB)

An example of one of the macros and scripts:

tell application "System Events"
	set CurrentPosition to position of window "PIP" of application process "PIPAgent"
	if item 1 of CurrentPosition is 20 then
		tell its application process "PIPAgent"
			tell its window "PIP"
				set position to {20, 42}
			end tell
		end tell
		tell its application process "PIPAgent"
			tell its window "PIP"
				set position to {1647, 42}
			end tell
		end tell
	end if
end tell

You are correct. So I have moved all of the discussion about AppleScript to a new topic.

1 Like