Re: I really need your help
Re: I really need your help
- Subject: Re: I really need your help
- From: has <email@hidden>
- Date: Sat, 9 Nov 2002 16:35:19 +0000
Michael Sullivan wrote:
>
Post your Script!
Yes indeedy; can't comment if there's nowt to comment on...:)
>
I'll just give you a quick hint -- the key to speeding up applescripts
>
is to cut down on the number of events that get passed. So try to get
>
the finder (or whatever you are driving to check/copy the files) to do
>
as many things in one AS instruction as possible. If you can copy a
>
whole folder or large group of files, instead of one file at a time,
>
your script will be much faster.
Yes and no. The number of events zooming back and forth may make a
significant difference, or it may not. e.g. Classic Finder is notorious for
dragging its heels for the fun of it; OS X Finder is much snappier and any
slowdown there is likely due to other factors.
It's too simplistic to say "the problem is messaging overhead". You need to
identify where (and why) the system is spending most of its time first. If
it's due to an inefficient algorithm in the script, replace it with a
better one. If it's the file copying that's taking time then there's
nothing you can usefully do to improve overall performance... except use
smaller files.;)
Cutting down on the number of events sent is in itself a
micro-optimisation. The real aim is improving the efficiency of your
script's algorithms; e.g. removing an entire loop and replacing it with a
single command. Getting rid of that loop is a macro-optimisation [1], and
the boost to performance follows from that.
>
Try getting all the information from the finder at once, using that
>
infomation (outside of a finder "tell block") to build a list of files
>
to be copied, another list of files to be deleted, etc. then find a way
>
to give that whole list (or large portions of it) to the finder in a few
>
instructions.
This can be done [2], but it's only easy to do up to a point.
It's easy to remove redundant items and duplicate fresh additions using
filter references; much easier than writing code to do it on a per-item
basis, in fact. But comparing items found in both folders is easier done
through the Finder, one at a time. All it requires is one loop to check
files, another to compare folders.
While you can pull lists of names and modification dates and work on those
without the Finder, the code required to munge that data is more complex
than this. If you spend all day writing it, only to discover the real
reason the script was slow is that it has to copy dozens of 20MB files
across a 10 Base-T network, then you're probably going to feel quite
foolish.;)
HTH
has
[1] i.e. By moving all the gruntwork to Finder, your AS algorithm's
efficiency improves from O(n) to O(1). Your communications overhead also
goes down, of course, but it was squeezing out that loop that made all the
difference. [Your overall algorithm is still O(n), of course, but now the
loop's happening in a much faster place.:]
[2] It's not immediately obvious that scriptable apps _can_ do this (and
quite forgivable if you never knew it before), but once you've seen it in
action it's the sort of technique you'll never forget (like riding a bike).
Funky.:)
======================================================================
-------
on deleteRedundantItemsInTargetFolder(srcFolder, trgFolder)
tell application "Finder"
set srcFileNames to name of every file of srcFolder
delete (every file of trgFolder whose name is not in
[NO-BREAK]srcFileNames)
set srcSubFolderNames to name of every folder of srcFolder
delete (every folder of trgFolder whose name is not in
[NO-BREAK]srcSubFolderNames)
end tell
return
end deleteRedundantItemsInTargetFolder
on copyItemsNotAlreadyInTargetFolder(srcFolder, trgFolder)
tell application "Finder"
set trgItemNames to name of every item of trgFolder
duplicate (every item of srcFolder whose name is not in
[NO-BREAK]trgItemNames) to trgFolder
end tell
return
end copyItemsNotAlreadyInTargetFolder
--
on listSrcFilesToCheck(srcFolder, trgFolder)
tell application "Finder"
set trgNames to name of every file of trgFolder
return every file of srcFolder whose name is in trgNames
end tell
end listSrcFilesToCheck
on listSrcSubFoldersToCheck(srcFolder, trgFolder)
tell application "Finder"
set trgNames to name of every folder of trgFolder
return every folder of srcFolder whose name is in trgNames
end tell
end listSrcSubFoldersToCheck
--
on listChangedSrcFiles(srcFilesToCheck, trgFolder)
set filesToCopy to {}
tell application "Finder"
repeat with srcFileRef in srcFilesToCheck
set fileName to srcFileRef's name
set trgFile to file fileName of trgFolder
if trgFile's modification date is not srcFileRef's
[NO-BREAK]modification date then -- note: includes newer files too!
set filesToCopy's end to srcFileRef's contents
end if
end repeat
end tell
return filesToCopy
end listChangedSrcFiles
-------
--MAIN
on backupFolder(srcFolder, trgFolder)
--sync easy stuff and get list of items to compare individually
deleteRedundantItemsInTargetFolder(srcFolder, trgFolder)
set filesToCheck to listSrcFilesToCheck(srcFolder, trgFolder)
set subFoldersToCheck to listSrcSubFoldersToCheck(srcFolder,
[NO-BREAK]trgFolder)
copyItemsNotAlreadyInTargetFolder(srcFolder, trgFolder)
--replace changed files
set filesToCopy to listChangedSrcFiles(filesToCheck, trgFolder)
tell application "Finder" to duplicate filesToCopy to trgFolder
[NO-BREAK]with replacing
--process subfolders recursively
repeat with srcFolderRef in subFoldersToCheck
tell application "Finder"
set folderName to srcFolderRef's name
set trgSubFolder to folder folderName of trgFolder
end tell
backupFolder(srcFolderRef's contents, trgSubFolder)
end repeat
return
end backupFolder
-------
--TEST
set srcFolder to alias "frank:work:"
set trgFolder to alias "joe:backup:"
backupFolder(srcFolder, trgFolder)
======================================================================
--
http://www.barple.pwp.blueyonder.co.uk -- The Little Page of AppleScripts
_______________________________________________
applescript-users mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/applescript-users
Do not post admin requests to the list. They will be ignored.