Re: More speed tests in offset handlers
Re: More speed tests in offset handlers
- Subject: Re: More speed tests in offset handlers
- From: Nigel Garvey <email@hidden>
- Date: Tue, 9 Oct 2001 02:45:35 +0100
Greg Back wrote on Mon, 08 Oct 2001 16:27:43 -0400:
>
On Mon, 08 Oct 2001 15:22:54 -0400, Arthur J Knapp at
>
email@hidden wrote
>
>
> You might find something in here more to your liking:
>
----SNIP----
>
>
I didn't get these in time to do a speed test. Have to go do some other
>
stuff soon. Anyone care to test for me??
Well...
>
-- Simple and short repeat loop:
>
--
>
on GetIndex(a, i)
>
if a contains i then repeat with x from 1 to a's length
>
if a's item x = i then return x
>
end repeat
>
return 0
>
end GetIndex
A more compact version of your own handler, probably about the same speed.
>
-- Binary-Search, split the list into smaller parts, makes great use
>
-- of the "contains" operator.
>
--
>
to BinarySearch(a, i, l, r)
>
if a's items l thru r contains i then
>
repeat until l = r
>
set m to (r + l) div 2
>
if a's items l thru m contains i then
>
set r to m
>
else
>
set l to m + 1
>
end if
>
end repeat
>
else
>
return 0
>
end if
>
end BinarySearch
Very similar to the binary search I posted, but offering the ability to
specify a search range within the list and using a different exit
criterion. It seems to be mostly faster than mine. (Gasp!) This is
because of the extra work mine does to reduce the length and number of
the intermediate lists. :-) Like mine, and yours, and the one above, it's
case-insensitive with strings. It'll work case-sensitively if the calling
line is encased (!) in a 'considering case' block.
considering case
BinarySearch({"Bill", "Fred", "Ethelstan"}, "fred", 1, 3)
end considering
--> 0
>
-- String-Coercable-Items Technique, (case-sensitive):
>
--
>
set the_list to {"abc", 123, true, "def"} -- all items coercable to a string
>
offsetOf(the_list, true)
>
>
property offsetSentinal : ASCII character 1 -- speed up repeated calls
>
>
on offsetOf(a, s) -- case-sensitive
>
set oldDelim to text item delimiters
>
set text item delimiters to offsetSentinal
>
set a to offsetSentinal & a & offsetSentinal
>
set x to offset of (offsetSentinal & s & offsetSentinal) in a
>
if (x is not 0) then
>
set x to count of text items in (a's text 1 thru x)
>
set x to x - 1
>
end if
>
set text item delimiters to oldDelim
>
return x
>
end offsetOf
The fastest method known to mankind, as all the looping is done by the
underlying low-level code rather than by the script itself. As Arthur's
noted, it only works with lists whose items are all coercible to string,
and its use of text item delimiters and 'offset' makes it case-sensitive.
Since it coerces the whole list to a single string, it's unable to
distinguish between non-string items and strings. Thus:
offsetOf({2 + 2 = 4, "aardvark", "true"}, "true")
--> 1
I won't mention the external property on which this handler depends as
Arthur's a good fr... Oops!
NG