FastScripts 3 speed issues with ASObjC scripts

I recently upgraded from FastScripts 2 to 3 and noticed a significant slowing with all of my scripts that employ ASObjC. To help sort this out, I wrote the scripts contained below and tested them with Script Geek. The ASObjC script was faster, taking 60 milliseconds as compared with 85 milliseconds for the basic AppleScript script.

I then ran these two scripts by way of FastScripts 3. The scripts were saved as scripts, and the only open app was Safari, which I resized after each run of each script. Even with all required frameworks in memory, there is a small but very noticeable delay when running the ASObjC script, but this delay is not present when running the basic AppleScript script.

Has anyone else noticed this, or am I doing something wrong? I’m running Monterey on a 2018 Mac mini. Thanks for the help.

BTW, I haven’t contacted Daniel about this yet, because I wanted to make sure I wasn’t doing something wrong. In my experience, Daniel is immensely helpful, and I will contact him (if warranted) after sorting out all the issues.

-- ASObjC script

use framework "AppKit"
use framework "Foundation"
use scripting additions

on main()
	set openApps to current application's NSWorkspace's sharedWorkspace()'s runningApplications()
	set thePredicates to current application's NSPredicate's predicateWithFormat:"activationPolicy == 0"
	set openApps to (openApps's filteredArrayUsingPredicate:thePredicates)'s valueForKey:"localizedName"
	repeat with anApp in openApps
		tell application "System Events" to tell process (anApp as text)
			tell every window
				set position to {50, 50}
				set size to {200, 200}
			end tell
		end tell
	end repeat
end main
main()
-- basic AppleScript script

on main()
	tell application "System Events" to set openApps to name of every process whose background only is false
	repeat with anApp in openApps
		tell application "System Events" to tell process (anApp as text)
			tell every window
				set position to {50, 50}
				set size to {200, 200}
			end tell
		end tell
	end repeat
end main
main()

I have similar problems with FastScripts 3 on Catalina.
All related to AppleScriptObjC:

Some scripts that call libraries will not load the frameworks they should, randomly. The result is that the first asoc method encountered will return an error.

Other scripts that load libraries to display complex dialogs are much less responsive, making their use a real challenge.

Catalina is known to be slow with Applescript. But with FastScripts 2.7.8, these problems disappear.

I hope that the installation of Monterey that I plan for the coming weeks will bring improvements on this front.

Jonas. Thanks for the information. I didn’t mention this before, but I’m running Monterey on a 2018 Mac mini. I emailed Daniel and hopefully he will be able to suggest a solution.

It’s the same for me. I hesitated for a long time, wondering if it was my configuration that is at issue. But after many weeks of intensive use of FastScripts 3, a few steps back (v 2.7.8) and a lot of rewriting, I can be (modestly) affirmative: there is something wrong.

I am also in touch with Daniel. As you said he’s very kind and willing to help. The main question is: is it FastScripts or macOs the responsible?

Thanks Jonas for the additional information. I emailed Daniel but he wasn’t able to reproduce the issue I was experiencing. I reinstalled FastScripts 2 and will use that for now. I have an old computer, and I suspect the issue I’m experiencing could be a result of that and nothing to do with FastScripts.

Only just catching up on this thread now. I’m sorry to hear the slowdown is affecting multiple people. Please don’t hesitate to get in touch about this kind of thing, even if you’re worried it might be "your own fault’ :slight_smile: If either of you, or anybody else, has any insights about how I might reproduce such a slowdown, that would be a good first step in trying to figure out how to reproduce it. I suspect whatever the difference is between FastScripts 2 vs 3 has to do with 3 launching a whole new process for every script. Maybe there is some once-per-process code that has to run when using ASObjC that slows things down. I’m not sure why I wouldn’t see the same slowdown here in my tests, though.

Perhaps a good test for each of you to try would be putting one of these scripts affected by the slowdown in a script application, forcing it to be run in a separate process no matter how it is run. I’d be curious if you see the same slowdown then when running the script even from FastScripts 2 or, for that matter, from anywhere else?

Daniel. When I first turn on my computer and run a script that uses ASObjC (regardless of how it’s run), there’s a small but noticeable pause while the frameworks used by the script are loaded into memory. Afterwards, the frameworks are apparently in memory and there is no pause the next time I run the script.

I know nothing about the operation of FastScripts 3, and less about when and how required frameworks are loaded into memory. However, I wondered if the frameworks are freshly loaded into memory every time an ASObjC script is run with FastScripts 3. This would account for the pause and would explain why I never encountered this pause with a script that uses basic AppleScript only. However, this would not explain why you are not experiencing the pause.

Yes, something like that sounds like it could be the cause. But in that case I guess a better question to figure out might be why the loading of the frameworks even causes a noticeable pause.

Daniel. The first time I run the script included below in Script Geek with no repetitions the timing result is 280 milliseconds. The second time I run the script the timing result is less than a millisecond. I encounter this all the time, and I assumed the difference was attributable to the required frameworks being loaded into memory, although I could easily be wrong about that.

This is also beyond my knowledge level, but I wondered if the time it takes to load the scripting bridge into memory might contribute towards the pause I notice. That’s just a guess, though.

use framework "Foundation"

set theString to current application's NSString's stringWithString:"Hello"

I wondered if the frameworks are freshly loaded into memory every time an ASObjC script is run with FastScripts 3.

I’ve particularly noticed this effect when using Dialog Toolkit Plus. Dialogs that appear instantaneously when run in Script Debugger take a noticeable moment in FastScripts. I had (however anecdotally) attributed this to the above cause.

Interesting.
Which version of macOS are you running?
And if you are using FastScripts, is it v2 or v3?

I think this delay is fairly typical for when the OSA Scripting component loads the necessary bridging files for ASObjC; I’d always noticed it with osascript (from the command line), which always starts a new process & has to load the bridging headers each time (unlike Script Debugger, which loads it once & reuses the Scripting Component). I’d always avoided ASObjC where possible because of the poor cold-start times.

Note that the slowdown/bridge loading only happens when a line of code calling/accessing ASObjC is actually used (i.e. a use framework "Foundation" on its own does not cause a slowdown).

Daniel, I’m not sure how FastScripts spawns the separate processes (in advance or on demand), but if the process were to first run an AppleScript similar to the below, that should take care of loading all the ASObjC bridge support prior to actually running a user script.

use framework "Foundation"
use framework "AppKit"
current application's NSString's |string|()
current application's NSWorkspace's sharedWorkspace()
return

(Edited to add AppKit call)

Oh, that’s a great idea. In fact the processes are typically spawned in advance, so that they are ready to go when a script is executed. So that could indeed make a significant impact. I’ll work on a beta update and share it here so people can test it out to confirm.

4 Likes

It might also be a good idea to load AppKit as well, since it’s used for a lot of things (not sure how much extra loading time it adds). I’ve updated the scriptlet above.

1 Like

Good idea to add AppKit, too. I made an experimental version of FastScripts that does this unilaterally at app launch time for each of the script runners, so it should have invoked a script like @tree_frog shared above by the time any user script is allowed to run in it.

https://redsweater.com/fastscripts/FastScripts3.2.3b3.zip

Let me know if anybody gives it a try, whether it makes any difference at all!

Daniel

1 Like

First impression is that my Dialog Toolkit Plus-based scripts are now working effectively instantaneously (as they do when run from Script Debugger) whereas previously there was a slight delay (maybe 0.5s on my older machine) when run from FastScripts.

In other words, it’s working. Will report back if there are any issues.

1 Like

Oh, that’s great. Thanks for the feedback @p1r2c1 … if there doesn’t seem to be any negative impact on scripts that DON’T use ASObjC then I’ll probably include this change in the next official update. Otherwise I’ll try to figure out a way to ensure these “pre-primed” versions of the script runners can be opted in to where appropriate.

1 Like

Daniel. I installed FastScripts version 3.2.3b3, and the pause I had experienced with the release version of FastScripts 3 is entirely gone. So, for me, FastScripts 3 is now every bit as fast as FastScripts 2. Many thanks :slight_smile:

1 Like

Amazing and wonderful news! Thanks for confirming.