Re: Text items
Re: Text items
- Subject: Re: Text items
- From: kai <email@hidden>
- Date: Fri, 19 Jan 2007 03:35:42 +0000
On 18 Jan 2007, at 02:10, I wrote:
On 17 Jan 2007, at 14:07, Adam Bell wrote:
to strip_extensions from q to e -- q is the original list, e the
occasional terminator
script o
property l : q -- casting a list as an embedded script
property assures that the list object is kept in memory for rapid
manipulation. Great speeder-upper for long lists.
Indeed. When accessing longer lists, one of the most effective
performance-enhancing methods is to introduce a referencing
technique, such as the 'a reference to' operator, or (better still)
a script object's property. (If the list is represented by a
property at the top level of the main script, qualifying the
property reference with 'my' or 'of me' also works.)
It's worth noting that, for short lists (of less than a dozen or so
items), initialisation of the script object can incur a small time
penalty (usually imperceptible at those levels). Beyond that, the
benefits become increasingly apparent.
Since there are evidently those who still seem sceptical about the
relevance of such referencing techniques, it might be an idea to take
a further brief look at this. While it has since turned out that the
list sizes involved in this particular thread aren't that critical,
it's still handy to understand the principles - and to apply them,
whenever there's a chance that a script might be used more widely.
If large amounts of data need to be handled every time an item in a
long list is accessed, then the total time required to access every
item in that list is bound to be exponential in nature. Referencing
provides a more efficient way of gaining access to each item, by
using a pointer to the specific location of the target data.
The following routine gives a glimpse of how this works. The results
show that more conventional methods (though perfectly adequate for
modest lists) involve the data from the entire list - in each and
every transaction. In contrast, the three methods mentioned above
refer only to the item's position within the relevant container.
(Some lines may need to be rejoined.)
--------------------
property main_script_property : {"Eeny", "meeny", "miny", "moe"}
to compare_list_access(script_variable, a_reference_to_variable)
script script_object
property object_property : script_variable
end script
set result_record to {| MAIN SCRIPT PROPERTY |:{}, | SCRIPT VARIABLE
|:{}, | MY MAIN SCRIPT PROPERTY |:{}, | A REFERENCE TO |:{}, | SCRIPT
OBJECT PROPERTY |:{}}
repeat with i in main_script_property
set result_record's | MAIN SCRIPT PROPERTY |'s end to i
end repeat
repeat with i in script_variable
set result_record's | SCRIPT VARIABLE |'s end to i
end repeat
repeat with i in my main_script_property
set result_record's | MY MAIN SCRIPT PROPERTY |'s end to i
end repeat
repeat with i in a_reference_to_variable
set result_record's | A REFERENCE TO |'s end to i
end repeat
repeat with i in script_object's object_property
set result_record's | SCRIPT OBJECT PROPERTY |'s end to i
end repeat
result_record
end compare_list_access
compare_list_access(main_script_property, a reference to
main_script_property)
--> {| MAIN SCRIPT PROPERTY |:{item 1 of {"Eeny", "meeny", "miny",
"moe"}, item 2 of {"Eeny", "meeny", "miny", "moe"}, item 3 of
{"Eeny", "meeny", "miny", "moe"}, item 4 of {"Eeny", "meeny", "miny",
"moe"}}, | SCRIPT VARIABLE |:{item 1 of {"Eeny", "meeny", "miny",
"moe"}, item 2 of {"Eeny", "meeny", "miny", "moe"}, item 3 of
{"Eeny", "meeny", "miny", "moe"}, item 4 of {"Eeny", "meeny", "miny",
"moe"}}, | MY MAIN SCRIPT PROPERTY |:{item 1 of main_script_property
of «script», item 2 of main_script_property of «script», item 3 of
main_script_property of «script», item 4 of main_script_property of
«script»}, | A REFERENCE TO |:{item 1 of main_script_property of
«script», item 2 of main_script_property of «script», item 3 of
main_script_property of «script», item 4 of main_script_property of
«script»}, | SCRIPT OBJECT PROPERTY |:{item 1 of object_property of
«script script_object», item 2 of object_property of «script
script_object», item 3 of object_property of «script script_object»,
item 4 of object_property of «script script_object»}}
--------------------
Of course, a hardened cynic might still question the efficacy of such
methods - so the following script attempts to provide a comparison.
(While I could re-quote previous figures, the ability to view the
results from one's own machine might be a more convincing indicator
of relative performance.)
Three access methods are compared, using:
• a regular variable
• the 'a reference to' operator
• a script object.
The number of listed items for each test is shown alongside the
corresponding access times (currently in milliseconds). As always
with this kind of comparison, individual results may fluctuate
somewhat - although the overall trends should give a fair idea of how
the techniques compare generally.
It's probably worth noting that each item is accessed only once in
each of these tests. However, many real-life situations involve a get-
value/set-value type of operation, which could cause any differences
to be amplified proportionally.
--------------------
(* requires appropriate timer: see get_time() handler *)
(* may take a while to execute, depending on machine *)
(* adjust properties below to suit your configuration *)
property start_count : 100 -- initial number of listed items
property end_count : 1500 -- final number of listed items
property add_count : 100 -- number of items added each time
to get_time()
GetMilliSec -- http://tinyurl.com/2mrq4v
-- the ticks -- http://tinyurl.com/2md6ne
end get_time
on access_time for l
set t to get_time()
repeat with i from 1 to count l
l's item i
end repeat
get_time() - t as integer
end access_time
on object_access_time for l
script o
property p : l
end script
set t to get_time()
repeat with i from 1 to count l
o's p's item i
end repeat
get_time() - t as integer
end object_access_time
set test_list to {0}
set result_list to {}
repeat with item_count from start_count to end_count by add_count
repeat while (count test_list) < item_count
set test_list to test_list & test_list
end repeat
set test_list to test_list's items 1 thru item_count
set result_list's end to {item_count}
delay 0.5
set end of result_list's end to access_time for test_list
delay 0.5
set end of result_list's end to access_time for a reference to
test_list
delay 0.5
set end of result_list's end to object_access_time for test_list
end repeat
set text item delimiters to tab & tab & tab
repeat with i in result_list
set i's contents to i as string
end repeat
set text item delimiters to tab & tab
set alrt to {"items", "variable", "a ref to", "object"} as string
set text item delimiters to return
set msg to result_list as string
set text item delimiters to {""}
display alert alrt message msg
--------------------
I do hope this helps to convince anyone who believes that referencing
methods offer no apparent advantage, or are merely thrown in for
effect. :-)
---
kai
_______________________________________________
Do not post admin requests to the list. They will be ignored.
AppleScript-Users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
Archives: http://lists.apple.com/mailman//archives/applescript-users
This email sent to email@hidden