Is there a faster way...

Ben Rubinstein benr at cogapp.com
Sun May 5 18:01:01 EDT 2002


on 3/5/02 5:03 PM, Bill Vlahos at bvlahos at jpl.nasa.gov wrote:

> repeat with i = 1 to the number of lines in field "Directory"
>    if item 1 of line i of field "Directory" & " " & item 2 of line i of
> field "Directory" <> vName then
>      put item 1 of line i of field "Directory" & " " & item 2 of line i
> of field "Directory" into tName
>      put tName & return after button "names" -- populate a popup button
> for navigation later
>      put tName into vName -- new Group/Task name
>    end if
>    put i into field "Records" -- show progress
> end repeat
> 
> I'm eventually going to have a hugh number of lines to process. This way
> will be too slow even though it only needs to go through the repeat loop
> once as the Group and Task names will already be sorted.
> 
> Is there a faster way?

In the loop, you have the expression (line i of field "Directory") four
times.  Each time, Rev must retrieve the text of the field (much slower than
retrieving contents of a variable), and walk through it counting line breaks
until it finds the "i'th" line.  So in the days of HyperCard, you would have
found a considerable speedup by doing this:

   put empty into button "names"
   put empty into vName
   put field "Directory" into theData -- only retrieve this once
   repeat with i = 1 to the number of lines in theData
     put line i of theData into oneLine -- find the line once
     if item 1 of oneLine & " " & item 2 of oneLine <> vName then
       put item 1 of oneLine & " " & item 2 of oneLine into tName
       put tName & return after button "names"
       put tName into vName
     end if
     put i into field "Records"
   end repeat

Actually you don't even need to access the line four times, as you calculate
the same expression twice:

   put empty into button "names"
   put empty into vName
   put field "Directory" into theData
   repeat with i = 1 to the number of lines in theData
     put line i of theData into oneLine
     put item 1 of oneLine & " " & item 2 of oneLine into tName
     if tName <> vName then
       put tName & return after button "names"
       put tName into vName
     end if
     put i into field "Records"
   end repeat

(that would have made a considerable difference, but now that the expression
is only parsing the single line, it probably doesn't do much.)

Because putting data into a button or field is even slower than getting it
out, depending on whether you expect to find a lot of unique names, it may
also be worth assembling this in a variable in the loop, so that it only
gets assigned to the button once:

   put empty into allNames
   put empty into vName
   put field "Directory" into theData
   repeat with i = 1 to the number of lines in theData
     put line i of theData into oneLine
     put item 1 of oneLine & " " & item 2 of oneLine into tName
     if tName <> vName then
       put tName & return after allNames -- accumulate
       put tName into vName
     end if
     put i into field "Records"
   end repeat
   put allNames into button "names"
 
Finally, Rev has a brilliant speed-up available: replace the counting loop
which requires Rev to locate the "i'th" line each time with a "for each"
loop, which allows Rev to just move a couple of pointers through the data:

   put empty into allNames
   put empty into vName
   put field "Directory" into theData
   put 1 into i -- now have to maintain progress counter explicitly
   repeat for each line oneLine in theData
     put item 1 of oneLine & " " & item 2 of oneLine into tName
     if tName <> vName then
       put tName & return after allNames
       put tName into vName
     end if
     put i into field "Records"
     add 1 to i -- now have to maintain progress counter explicitly
   end repeat
   put allNames into button "names"

My guess is that by the time you've done all that, you'll be down to a
second or so.  If not - then remove the probably redundant progress
indicator (remember that putting text into fields is quite slow) and it will
be.
 
  Ben Rubinstein               |  Email: benr_mc at cogapp.com
  Cognitive Applications Ltd   |  Phone: +44 (0)1273-821600
  http://www.cogapp.com        |  Fax  : +44 (0)1273-728866





More information about the use-livecode mailing list