Re: Suggestions for speeding up code
Re: Suggestions for speeding up code
- Subject: Re: Suggestions for speeding up code
- From: James Burns <email@hidden>
- Date: Fri, 28 Feb 2003 08:23:28 -0500
Kai:
You're the best. I haven't tried it, yet, but it makes great sense on
the first read-through.
I wonder why doesn't my mind work this way? I guess I'm good at other
things (like Graphic Design).
Things I found particularly useful/helpful:
1/ The method of extracting the info - neat and elegant
2/ The mention that you can loop through a container by "paragraphs."
- do you mean that the tids can be set to "paragraph" the same way it
can be set to "space" or "return", or what? I didn't run across that
word in any of the AppleScript docs.
3/ The use of "run script." Do you mean it evaluates a variable? Can I
have test="Bite me!" and use "do script test" to return Bite me? I'll
have to read up on it...
By the way... I set the variable oldDelims at the start of my (larger)
script.
Thanks for all of your help. When I release my (free) utility, I'll be
sure to mention all of your help.
-----
James Burns
http://www.jamesburnsdesign.com
Subject: Re: Suggestions for speeding up code
From: Kai <email@hidden>
To: <email@hidden>
on Tue, 25 Feb 2003 16:26:31 -0500, James Burns
<email@hidden>
wrote:
This list has been very helpful since I started reintroducing myself
to
Applescript, and I was wondering if i could impose just one more time.
Just *one* more time, James? I hope you're not planning on leaving us!
;-)
Well, it's been a few days since you posted this - and not even a
nibble so
far, so I'll bite - guess you'll just have to put up with me for now!
I've been writing a program in AppleScript Studio (with everyone's
kind
help) and am at the point where I'm trying to optimize my code for
speed. It seems that the following handler takes the most time (3 or 4
seconds, roughly) to read a file, and extract some stuff from it.
That's a good start. You've already identified the most serious
bottleneck.
The file is a text file with the following format:
...
keyWord value
keyWord value
keyWord value
keyWord value
...
Some of the values are numbers, some can be full paths for files or
directories. I want to extract the value that follows the keyword.
Here's how I'm going about it (be gentle, please):
Relax, James. We're all pussycats around here (most of the time). ;-)
(Prior to this handler I've opened the file and tested it it contained
some text to see if it was set up right. The global "output" contains
the file contents...)
Great. It's always handy to have this kind of background information
when
working with isolated code snippets.
Besides the performance issues about which you asked, I've also tried
to
abbreviate the script slightly to (hopefully) make it a little easier
to
digest.
My first query relates to the use of the variable 'output' as a global.
Unless a variable needs to be accessed by numerous subroutines, I
generally
localise its use and pass its value between handlers. (In a long
script,
this also helps to clarify the external value(s) required by a
handler.)
I guess you were using the line <log "Started extractStuff handler">
for
either debugging or timing but, since it's obviously not essential to
the
finished script, we can now probably lose it. However, your script also
tries to reset TIDs to the value of 'oldDelims', which is currently
missing
(presumably because of a copy/paste slip) - so we need to set that.
I see that, to search the text, the three variables (FirstFrame,
LastFrame
and FrameStep) are set to their string equivalents. These are later
reset to
the values found in the text. I opted instead to use the search strings
directly - and then add the three found values to the variable
'stuffToGet'
(which I initially set as an empty list). Both methods work fine, but
the
latter allows for a slightly shorter script.
Now we come to the crux of the speed issues.
Your script uses two repeat loops, one to define the keyword that
needs to
be found - and another to find that keyword in the text (represented
by the
variable 'output').
The first loop is necessary to search for more than one keyword.
(Instead of
setting TIDs to 'return' and then looping through 'text items', it
might
have been easier to simply loop through 'paragraphs' instead. However,
I'm
going to suggest an entirely different method.)
It's the second, nested loop that's probably causing the greatest
delay -
and this is where AppleScript's text item delimiters can be used to
great
effect. Instead of isolating the value of keywords in each line of
text, we
could use the TIDs to work on the entire text - which is much faster.
BTW, I've assumed that each listed keyword is separated from its value
by a
tab. If that's not the case, my suggestion will need adjusting
slightly. In
addition, if a keyword can't be found, the user is given the option of
continuing with an empty string in place of the missing value (which
may or
may not be desirable behaviour).
Anyway, I'd suggest something like this:
===========================
to extractStuff from output
set {oldDelims, stuffToGet} to {text item delimiters, {}}
repeat with searchWord in {"FirstFrame", "LastFrame", "FrameStep"}
set text item delimiters to searchWord & tab
try
set val to output's text item 2
on error number -1728
set {text item delimiters, val} to {oldDelims, return}
display dialog "Continue with \"\" as " & searchWord & "'s value?"
end try
set text item delimiters to return
set {stuffToGet's end, text item delimiters} to [NO-BREAK]
{val's text item 1, oldDelims}
end repeat
stuffToGet
end extractStuff
set {FirstFrame, LastFrame, FrameStep} to extractStuff from output
-- do something with {FirstFrame, LastFrame, FrameStep}
===========================
I assume you already know how you're going to deal with the resulting
values
(which will still be strings). In case it might be useful, I'll just
mention
that strings containing file references, numbers etc. may be converted
to
values of the appropriate class by using 'run script'. For example:
===========================
run script "38"
--> 38
run script "5.25 * 2"
--> 10.5
run script "alias \"Macintosh HD:James Burns:text file\""
--> alias "Macintosh HD:James Burns:text file"
-- (*will error if the item doesn't exist*)
===========================
The main difference between the two scripts is the time taken to find
each
keyword's value - which, for the original, is directly proportional to
the
length of the list in 'output'. For all intents and purposes, the
modified
version is relatively unaffected by this - taking about the same time
to
extract values from almost any list.
To demonstrate this, I've tabled below some results taken from my
machine.
The first column shows how many items were in the list, while the
second
indicates the time taken by the original script (compared to that
taken by
the modified version). The results are expressed as an index (the time
taken
by the modified version = 1 in every case).
--------------------
index: fastest = 1
--------------------
----- ---------
list slowest
count (original)
----- ---------
10 --> 5
20 --> 7
30 --> 10
40 --> 13
50 --> 16
100 --> 38
1000 --> 400
--------------------
(So if your list contained 10 items and the original handler took 5
seconds
on your machine, the modified version should do it in about a second;
if
your machine extracted values from a 20 item list in 3.5 seconds, you
should
now get them in about half a second - and so on...)
HTH
--
Kai
_______________________________________________
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.