Re: Strange Bottleneck
Re: Strange Bottleneck
- Subject: Re: Strange Bottleneck
- From: Nigel Garvey <email@hidden>
- Date: Mon, 9 Jun 2003 00:10:35 +0100
Steve Cunningham wrote on Sun, 8 Jun 2003 05:18:44 -0400:
>
Thanks, Nigel! I was really getting frustrated. Adding the "my" does
>
indeed seem to make the times independent of "newRow" and salvage the
>
script. However...
>
>
I am disappointed that it doesn't work as written. What is "the Serge
>
method"?
Hi, Steve. There's nothing wrong with the way your script was written.
It's just that the way list access is implemented "under the bonnet", it
can get very slow with long lists.
The Serge method is named after Serge Belleudy-d'Espinose, who
popularised it a year or two ago. He noticed that, in a handler, if a
list was made a property of a script object, access to it was very much
faster than otherwise:
on myHandler(longList)
script o
property spLongList:longList
end script
-- Slow
repeat with i from 1 to 4000
item i of longList
end repeat
-- Fast
repeat with i from 1 to 4000
item i of o's spLongList
end repeat
end myHandler
Research suggests that the second loop is faster because it refers to the
list by a reference expression - "o's spLongList" (two words) - rather
than just a variable name. According to Chris Nebel, this referential
approach sidesteps certain time-consuming safety checks that are built
into list accesses. The last I heard, some soul-searching was going on at
Apple about whether these checks are really necessary.
The idea then is to engineer a situation where you can use a reference
expression to refer to the list. In your script, the line of code that
refers to the list is inside a script object where the list variable has
global scope. You *could* make another script object within the script
object and refer to it that way, but here you may as well just use "my".
In your script, "my columns" equates to "columns of script matrix".
One important thing to remember is that the speed gain only comes about
when you're accessing numbered positions in the list - eg. "item i of o's
longList", "items 1 thru 7 of o's longList" - or when you're *getting*
its "rest", "end", or "beginning". With expressions such as "set end of",
"set beginning of", "is in", or "contains", using a straight variable is
just as fast as using a reference and is usually a tad faster.
>
After two days of testing different methods and timings, I had
>
pretty much narrowed the problem down to the "item nn of columns", but
>
couldn't understand what was going on. The only variable that changes
>
with "newRow" is that an additional item is added to the end of each
>
column on each iteration. In fact, you can replace the whole
>
"insert_item" call with
>
>
set the end of item nn of columns to item nn of valueList
>
>
and get the same result... with the same miserable performance :-(
I haven't tried this with your script but you might be able to speed it
up even more. Besides using "my" in front of "columns", you could set up
a script object inside your "insertRow" handler to speed up access to
"valueList"'s items:
on insertRow(newRow, valueList)
script o
property spValueList:valueList
end script
-- Then later on:
set item nn of my columns to insert_listitem(item nn of my columns,
item nn of o's spValueList, newRow)
There are a number of ways you could arrange this. You'd have to decide
which you found clearest and easiest to handle.
>
If you can point me to a reference that explains it, I'd appreciate it.
I don't know of any, I'm afraid, apart from previous discussions on this
list or MACSCRPT. The AppleScript Language Guide briefly mentions that
the use of reference variables instead of the original list variables can
things up, but doesn't say why:
set myList to {<- 4000 items ->} -- don't try compiling this!
set listRef to a reference to myList
repeat with i from 1 to 4000
item i of listRef
end
This only works at the top level of a script, not in a handler. The value
of listRef is the reference "myList of <<script>>". Instead of listRef,
you could use "my myList", which also means "myList of <<script>>". The
difference is that with "my", the reference is compiled directly into the
script instead of being held in a variable, and gives faster results.
NG
_______________________________________________
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.