Sunday, May 9, 2021

#1 2021-04-29 09:19:31 am

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 871

Extract a Value from a List of Lists - Timing Test Results

I often use a list of lists in scripts and wondered what might be the best approach to extract a particular value. So, I ran some timing tests.

First, I used the following code to create a list of lists with 3000 sublists. To allow me to verify that the script being tested was working correctly, I set item 2 of sublists 1 through 2999 to "a" and item 2 of sublist 3000 to "b".

Applescript:

-- untimed code
set theListOfLists to {}
repeat with i from 1 to 3000
   if i < 3000 then
       set theCharacter to "a"
   else
       set theCharacter to "b"
   end if
   set the end of theListOfLists to {i, theCharacter}
end repeat

The timing script I used was the one in post 16 of the following thread. I ran the timing tests twice and recompiled the script before the first but not the second running of the script.

https://macscripter.net/viewtopic.php?id=47102

It should be noted that with smaller lists any of the following will do the job. For example, If the list of lists contains 100 sublists, script 1 only takes 0.002 second to run. In my testing, the point at which a script begins to benefit from the speed enhancements contained in the other scripts is around 300 sublists.

1) A REPEAT LOOP WITH BASIC APPLESCRIPT

Applescript:

set itemTwo to getTheItem(theListOfLists, 3000)

on getTheItem(theListOfLists, itemOne)
   repeat with i from 1 to (count theListOfLists)
       if item 1 of (item i of theListOfLists) = itemOne then
           return item 2 of (item i of theListOfLists)
       end if
   end repeat
end getTheItem

-- elapsedTime --> 8.333 second - 8.334 second

2) ASOBJC (Thanks Nigel)

Applescript:

set itemTwo to getTheItem(theListOfLists, 3000)

on getTheItem(theListOfLists, ItemOne)
   set theArrayofArrays to current application's NSArray's arrayWithArray:theListOfLists
   set filter to current application's NSPredicate's predicateWithFormat_("self[FIRST] == %@", ItemOne)
   return (((theArrayofArrays's filteredArrayUsingPredicate:(filter)) as list)'s end's end)
end getTheItem

-- elapsedTime --> 0.045 second - 0.042 second

3) A REPEAT LOOP UTILIZING "A REFERENCE TO"

Applescript:

set itemTwo to getTheItem(a reference to theListOfLists, 3000)

on getTheItem(theListOfLists, itemOne)
   repeat with i from 1 to (count theListOfLists)
       if item 1 of (item i of theListOfLists) = itemOne then
           return item 2 of (item i of theListOfLists)
       end if
   end repeat
end getTheItem

-- elapsedTime --> 0.018 second - 0.015 second

4) A REPEAT LOOP UTILIZING A SCRIPT OBJECT

Applescript:

set itemTwo to getTheItem(theListOfLists, 3000)

on getTheItem(theListOfLists, ItemOne)
   script o
       property listRef : theListOfLists
   end script
   repeat with i from 1 to (count o's listRef)
       if item 1 of (item i of o's listRef) = ItemOne then
           return (item 2 of (item i of o's listRef))
       end if
   end repeat
end getTheItem

elapsedTime --> 0.009 second - 0.006 second

5) A REPEAT LOOP UTILIZING AN IMPLICIT SCRIPT OBJECT

Applescript:

set itemOne to 3000

repeat with i from 1 to (count my theListOfLists)
   if item 1 of (item i of my theListOfLists) = itemOne then
       set ItemTwo to item 2 of (item i of my theListOfLists)
       exit repeat
   end if
end repeat

-- elapsedTime --> 0.006 second - 0.003 second

Last edited by peavine (2021-04-30 07:01:41 am)


2018 Mac mini - macOS Catalina

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)