Optimizing an AppleScript for speed...

So, I have an AppleScript that works. It does the job. This makes me happy, in that I got to the end goal by myself. But this script is dog slowwwww (because there could be 80-100 settings in the Custom Settings folder that get moved one by one.)

Dead dog slow. But reliable.

So, I’m wondering where did I go wrong in writing this script? Where are the places that I could have been smarter. Are there unnecessary loops? Could I do everything at once, instead of doing the repeat steps, for example?

Note: The script doesn’t currently check to see whether or not FCP is installed (obviously the Custom Settings folder would not exist if it’s not installed).



global xfolder
global theresponse

display dialog ("FCP Easy Setup Remover is a utility for simplifying the an editor's choices when working in Final Cut Pro." & return & return & "It lets you limit your settings choices to only the Easy Setups you use most." & return & return & "Unwanted Easy Setups are archived and can be restored at any time.")
set homefolder to (path to documents folder) as Unicode text
tell application "Finder"
	if (exists item "FCP Easy Setup Backups" of folder homefolder) then
	
		display dialog "Do you want to Archive Some Easy Setups or Restore Easy Setups from the Archive:" buttons {"Archive", "Restore", "Quit"} default button 1
		
		
		if the button returned of the result is "Quit" then
			error number -128
		else
			if the button returned of the result is "Archive" then
				
				set xfolder to (((path to library folder) as text) & "Application Support:Final Cut Pro System Support:Custom Settings:") as alias
				
				tell application "Finder"
					set theSettings to (name of every file of xfolder)
					set chosenSettings to (choose from list theSettings with prompt "Choose the settings you want to archive:" with multiple selections allowed)
				end tell
				repeat with i from 1 to (count of every item of chosenSettings)
					tell application "Finder"
						set y to file (item i of chosenSettings) of xfolder
						
						
						if (exists item "FCP Easy Setup Backups" of folder homefolder) then
							move y to (homefolder & "FCP Easy Setup Backups:")
							
						else
							make new folder at homefolder with properties {name:"FCP Easy Setup Backups"}
							move y to (homefolder & "FCP Easy Setup Backups")
						end if
						
						
					end tell
				end repeat
			else
				if the button returned of the result is "Restore" then
					
					set xfolder to (((path to library folder) as text) & "Application Support:Final Cut Pro System Support:Custom Settings:") as alias
					set yfolder to (((path to documents folder) as text) & "FCP Easy Setup Backups:") as alias
					tell application "Finder"
						set theSettings to (name of every file of yfolder)
						set chosenSettings to (choose from list theSettings with prompt "Choose the settings you want to archive:" with multiple selections allowed)
					end tell
					repeat with i from 1 to (count of every item of chosenSettings)
						try
							tell application "Finder"
								set y to file (item i of chosenSettings) of yfolder
								
								move y to xfolder
								
								
								
							end tell
							
						end try
					end repeat
				end if
			end if
		end if
	else
		set xfolder to (((path to library folder) as text) & "Application Support:Final Cut Pro System Support:Custom Settings:") as alias
		
		tell application "Finder"
			set theSettings to (name of every file of xfolder)
			set chosenSettings to (choose from list theSettings with prompt "Choose the settings you want to archive:" with multiple selections allowed)
		end tell
		repeat with i from 1 to (count of every item of chosenSettings)
			tell application "Finder"
				set y to file (item i of chosenSettings) of xfolder
				
				
				if (exists item "FCP Easy Setup Backups" of folder homefolder) then
					move y to (homefolder & "FCP Easy Setup Backups:")
					
				else
					make new folder at homefolder with properties {name:"FCP Easy Setup Backups"}
					move y to (homefolder & "FCP Easy Setup Backups")
				end if
				
				
			end tell
		end repeat
	end if
end tell


Second question: This script works well if an admin runs it, not so good when you are a non-admin. Is there a way to make it work for both types of user accounts?

Cheers!

The obvious question is: which part is slow?

Looking at the script it’s clear that you’re interacting with the user to work out what to do, then you run a series of Finder commands to move data around.

Since the UI code is pretty straightforward I can only think you’re referring to the file copy code. There isn’t much you can do about that since it’s being handled by the Finder and will depend on disk speed, etc. - it’ll only go as fast as the Finder can copy the data.

If it’s some other area that seems slow, please let us know.

I updated my original question. The slowness comes in two places. First, it takes about 10 seconds for it to go from interactive message to another. That’s relatively minor. But then, there could be 80-100 setting in the Custom Settings folder that need to be moved (the goal is to only keep maybe 5 or 6 settings in the folder). This script diligently goes through moving each one, but each repeat cycle takes about 15-20 seconds. So, to do the whole folder takes a long time.

So, I guess is there a way to tell the Finder to move a block of files instead of one at a time?

Cheers.

Hi.

Looking quickly at your script, there are a few things that might be done differently. But one that particularly catches my eye speedwise is that you’re testing for the existence of the same folder (“FCP Easy Setup Backups”) on every iteration of the repeats in which it’s used, which would make things take twice as long. You’ve already tested for it at the top of the script. The first repeat is only executed if it does exist, so you don’t need to test at all there. The last repeat is only executed if it doesn’t exist, in which case you should create it before entering the repeat.

However, Instead of repeating to move the files one at a time, you could give the Finder one command to move every file of the folder whose name is in chosenSettings to the destination you have in mind.

I haven’t run this, but if your original script works, this should:

global xfolder
global theresponse

display dialog ("FCP Easy Setup Remover is a utility for simplifying the an editor's choices when working in Final Cut Pro." & return & return & "It lets you limit your settings choices to only the Easy Setups you use most." & return & return & "Unwanted Easy Setups are archived and can be restored at any time.")
set homefolder to (path to document folder as Unicode text)
tell application "Finder"
	if (exists item "FCP Easy Setup Backups" of folder homefolder) then
		
		display dialog "Do you want to Archive Some Easy Setups or Restore Easy Setups from the Archive:" buttons {"Archive", "Restore", "Quit"} default button 1
		set action to button returned of result
		
		if action is "Quit" then
			error number -128
		else if action is "Archive" then
			
			set xfolder to ((path to application support as text) & "Final Cut Pro System Support:Custom Settings:") as alias
			
			tell application "Finder"
				set theSettings to (name of every file of xfolder)
				set chosenSettings to (choose from list theSettings with prompt "Choose the settings you want to archive:" with multiple selections allowed)
				if (chosenSettings is false) then error number -128
				
				-- This code is being executed, so we know folder "FCP Easy Setup Backups:" exists.
				move (every file of xfolder whose name is in chosenSettings) to folder (homefolder & "FCP Easy Setup Backups:")
			end tell
		else -- action must be "Restore".
			
			set xfolder to ((path to application support as text) & "Final Cut Pro System Support:Custom Settings:") as alias
			set yfolder to ((path to document folder as text) & "FCP Easy Setup Backups:") as alias
			tell application "Finder"
				set theSettings to (name of every file of yfolder)
				set chosenSettings to (choose from list theSettings with prompt "Choose the settings you want to archive:" with multiple selections allowed)
				if (chosenSettings is false) then error number -128
				
				move (every file of xfolder whose name is in chosenSettings) to yfolder
			end tell
		end if
	else -- item "FCP Easy Setup Backups" of folder homefolder doesn't exist.
		set xfolder to ((path to application support as text) & "Final Cut Pro System Support:Custom Settings:") as alias
		
		tell application "Finder"
			set theSettings to (name of every file of xfolder)
			set chosenSettings to (choose from list theSettings with prompt "Choose the settings you want to archive:" with multiple selections allowed)
			if (chosenSettings is false) then error number -128
			
			-- This code is being executed, so we know folder "FCP Easy Setup Backups:" DOESN'T exist. Create it now.
			set destFolder to (make new folder at folder homefolder with properties {name:"FCP Easy Setup Backups"})
			move (every file of xfolder whose name is in chosenSettings) to destFolder
		end tell
	end if
end tell

That’s great. The existence check being done multiple times was a good catch. I’ve made that change and that helps already. I will do the multiple move change tonight.

Thanks.

A.

OK, so much faster now. Awesome thank you.

I have one more thing to figure out. In the Custom Settings folder, sometimes there will be a subfolder in it like “IO HD” or “Kona Settings” and the script doesn’t pick up on those settings. Plus, I can’t predict what the subfolder names might be.

Is there a way for the finder to make a list of the items in a folder and its subfolders so that you can get a complete list of files?

Here is what I have so far:




global xfolder
global theresponse

-- INTRO

display dialog ("FCP Easy Setup Remover is a utility for simplifying an editor's choices when working in Final Cut Pro." & return & return & "It lets you limit your settings choices to only the Easy Setups you use most." & return & return & "Unwanted Easy Setups are archived and can be restored at any time.") with title "FCP Easy Setup Simplifier"
display dialog ("In order for the Easy Setup list to reflect the changes we are making in Final Cut Pro, this program needs to delete the Final Cut Pro User Prefs. If there are other User Accounts on this computer, you will need to manually toss the FCP prefs for the other users (the three files located in ~/Library/Preferences/Final Cut Pro User Data.)" & return & return & "Note: This program has only been tested in Leopard and with Final Cut Pro 6. You need to be an admin user to run the script.") with title "FCP Easy Setup Simplifier"

-- MAIN SCRIPT


set homefolder to (path to documents folder) as Unicode text
tell application "Finder"
	
	-- Check for Backup Folder. If it exists then Restor is possible
	
	if (exists item "FCP Easy Setup Backups" of folder homefolder) then
		
		display dialog "Do you want to Archive Some Easy Setups or Restore Easy Setups from the Archive?" with title "FCP Easy Setup Simplifier" buttons {"Archive", "Restore", "Quit"} default button 1
		
		
		if the button returned of the result is "Quit" then
			error number -128
		else
			
			-- ARCHIVE SECTION where Backup Folder already exists
			
			if the button returned of the result is "Archive" then
				
				set xfolder to (((path to library folder) as text) & "Application Support:Final Cut Pro System Support:Custom Settings:") as alias
				
				tell application "Finder"
					set theSettings to (name of every file of xfolder)
					set chosenSettings to (choose from list theSettings with prompt "Choose the settings you want to archive:" with multiple selections allowed)
					if (chosenSettings is false) then error number -128
					move (every file of xfolder whose name is in chosenSettings) to folder (homefolder & "FCP Easy Setup Backups:")
				end tell
				
				-- This part tosses the FCP Prefs
				
				tell application "Finder"
					try
						set prefspath to (((path to library folder from user domain) as text) & "Preferences:Final Cut Pro User Data:")
						set PrefDelete to (prefspath & "Final Cut Pro 6.0 Prefs.fcset") as alias
						set ObjCacheDelete to (prefspath & "Final Cut Pro Obj Cache.fcmch") as alias
						set ProfCacheDelete to (prefspath & "Final Cut Pro Prof Cache.fcpch") as alias
						move PrefDelete to trash
						move ObjCacheDelete to trash
						move ProfCacheDelete to trash
					end try
				end tell
				
			else
				
				-- This part copies files from the Backup into the Custom Settings
				
				if the button returned of the result is "Restore" then
					
					set xfolder to (((path to library folder) as text) & "Application Support:Final Cut Pro System Support:Custom Settings:") as alias
					set yfolder to (((path to documents folder) as text) & "FCP Easy Setup Backups:") as alias
					try
						tell application "Finder"
							set theSettings to (name of every file of yfolder)
							
							set chosenSettings to (choose from list theSettings with prompt "Choose the settings you want to restore:" with multiple selections allowed)
							if (chosenSettings is false) then error number -128
							move (every file of yfolder whose name is in chosenSettings) to xfolder
							
							
						end tell
						
						-- This part tosses the FCP Prefs
						
						
						tell application "Finder"
							try
								set prefspath to (((path to library folder from user domain) as text) & "Preferences:Final Cut Pro User Data:")
								set PrefDelete to (prefspath & "Final Cut Pro 6.0 Prefs.fcset") as alias
								set ObjCacheDelete to (prefspath & "Final Cut Pro Obj Cache.fcmch") as alias
								set ProfCacheDelete to (prefspath & "Final Cut Pro Prof Cache.fcpch") as alias
								move PrefDelete to trash
								move ObjCacheDelete to trash
								move ProfCacheDelete to trash
							end try
						end tell
					on error
						display dialog "No Settings to restore"
						quit
					end try
				end if
			end if
		end if
	else
		
		-- If Backup folder doesn't exists, then we need to make one. And no restore possible. 
		
		set xfolder to (((path to library folder) as text) & "Application Support:Final Cut Pro System Support:Custom Settings:") as alias
		
		tell application "Finder"
			set theSettings to (name of every file of xfolder)
			try
				set chosenSettings to (choose from list theSettings with prompt "Choose the settings you want to archive:" with multiple selections allowed)
			on error
				display dialog "No settings to Archive" with title "FCP Easy Setup Simplifier"
			end try
		end tell
		
		-- We create the new folder here
		
		tell application "Finder"
			make new folder at homefolder with properties {name:"FCP Easy Setup Backups"}
			
			-- Here we copy the files to the folder. 
			
			move (every file of xfolder whose name is in chosenSettings) to folder (homefolder & "FCP Easy Setup Backups:")
			
		end tell
		
		-- This part tosses the FCP Prefs
		
		tell application "Finder"
			try
				set prefspath to (((path to library folder from user domain) as text) & "Preferences:Final Cut Pro User Data:")
				set PrefDelete to (prefspath & "Final Cut Pro 6.0 Prefs.fcset") as alias
				set ObjCacheDelete to (prefspath & "Final Cut Pro Obj Cache.fcmch") as alias
				set ProfCacheDelete to (prefspath & "Final Cut Pro Prof Cache.fcpch") as alias
				
				move PrefDelete to trash
				move ObjCacheDelete to trash
				move ProfCacheDelete to trash
			end try
		end tell
		
	end if
end tell


You can get all the files in a folder and its subfolders by using its ‘entire contents’ property:

tell application "Finder"
	set theSettings to (name of every file of entire contents of xfolder)
	set chosenSettings to (choose from list theSettings with prompt "Choose the settings you want to archive:" with multiple selections allowed)
	if (chosenSettings is false) then error number -128
	move (every file of entire contents of xfolder whose name is in chosenSettings) to folder (homefolder & "FCP Easy Setup Backups:")
end tell

One problem with this is that, if a file in a subfolder has the same name as a file in another subfolder, or the same name as a file in the folder itself, there’ll be a name conflict at the destination, which will result in an error.

Another problem of course is that there’s no way to return files to their original subfolders when the move goes the other way. My guess is that you’d want to move the subfolders themselves rather than individual files from them. If that’s the case, you’d use ‘every item of’ rather than ‘every file of entire contents of’:

tell application "Finder"
	set theSettings to (name of every item of xfolder)
	set chosenSettings to (choose from list theSettings with prompt "Choose the settings you want to archive:" with multiple selections allowed)
	if (chosenSettings is false) then error number -128
	move (every item of xfolder whose name is in chosenSettings) to folder (homefolder & "FCP Easy Setup Backups:")
end tell

Nice. I will try that. Thank you.

Cheers.

A.