At 00:23 27/11/00 +0100, Daniel Plenitz wrote:

>>E.g. I want to delete the items number 3, 5, 8 from a list
>>of 10 items. Once the item 3 has been deleted, the item 5 became
>>4 and the item 8 became 7.
>
><snip a long startmovie handler and a short tool handler>

A so long snip would require a short info: the long startmovie
handler was for Director's beginners, like me, who ever look
for paste-&-try scripts.
About the short tool handler, I beg to differ: it's long and time
consuming.

>Another way to avoid that sort of problems would be to perform the series 
>of deletions in back-to-front order; i.e. first delete item 8, next item 5 
>and in the end item 3. Lingo supports this approach with the
>
>repeat with variable = startValue down to endValue
>
>syntax

The back-to-front order, that's well-known to be a bit faster than
the front-to-back order, is not sufficient per-se to speed up the
deletion of a number of items. BTW it needs sorted items.

The problem of the "Index out of range" error is avoided by a
linearList.sort(), while the problem of the deletion speed seems
not much influenced by the order of the repeat loop.

This is the second aspect of the question that pushed me to prefer the
front-to-back order, btw I followed your suggestion and rewrote it:

on deleteSubset_A items, itemsToDelete
  dcnt = itemsToDelete.count()
  repeat with i = dcnt down to 1
    items.deleteAt(i)
  end repeat
  return items
end

As I said, no matter the order of the repeat loop, under some
conditions (see at the bottom) the use of .deleteAt() is 40 times
slower of the following type of deletion:

on deleteSubset_B items, itemsToDelete
  icnt = items.count()
  dcnt = itemsToDelete.count()
  local = []
  repeat with i = 1 to dcnt
    items[itemsToDelete[i]] = VOID
  end repeat
  repeat with i = 1 to icnt
    if not voidP(items[i]) then local.append(items[i]) 
  end repeat
  return local
end

To see the handlers in action:

on startMovie
  -- Fill the list characters with 50000 characters in the set A-Z
  characters = []
  repeat with i = 1 to 50000
    characters[i] = numToChar(64 + random(26))
  end repeat
  
  -- Define a list of indexes of characters to delete from characters[]
  charactersToDel = []
  repeat with i = 1 to 25000
    charactersToDel[i] = i
  end repeat
  
  -- Delete and display the result
  startTimer
  characters = deleteSubset_A(characters, charactersToDel) -- _B<->_A
  put (the timer/ 60.0) && "sec"
  put "characters left =" && characters.count()
end

--  items  itemsToDel     deleteSubset_A()  deleteSubset_B()
--
--  50000        1000           4.8000 sec        1.2567 sec
--  50000        2000           8.2833 sec        1.2533 sec
--  50000        3000          11.6667 sec        1.2500 sec
--  50000        4000          16.4167 sec        1.2433 sec
--  50000        5000          21.3000 sec        1.2333 sec
--  50000       10000          27.2167 sec        1.1667 sec
--  50000       15000          39.2333 sec        1.1500 sec
--  50000       20000          46.0167 sec        1.1333 sec
--  50000       25000          46.7333 sec        1.0833 sec
--  50000       30000          38.2667 sec        1.0167 sec
--  50000       35000          33.1500 sec        0.9833 sec
--  50000       40000          24.9667 sec        0.9167 sec
--  50000       45000          10.1833 sec        0.9000 sec      
--  50000       50000           0.4000 sec        0.8833 sec

Last notations:

1 - .deleteAt() is strongly non-linear. This seems to me a _feature_
    and not a defect, for the sake of clarity.

2 - Depending upon the expected ratio items/itemsToDel a decision can
    be made about the use of deleteSubset_A() or deleteSubset_B().
    Eventually try your lists with my code as a starting point.

3 - deleteSubset_B() doesn't require a sorted list for itemsToDelete.
    In turn, deleteSubset_B() does requires it, but the list has not
    been sorted in the above example for how it is builded.

4 - Errata Corrige: in my previous message about this subject I wrote:
    "...referring to the call of the example above it should be
     replaced with:
    itemsLeft = deleteSubset(metals, metalsToDel.sort())"
    This does not work because metalsToDel.sort() is not a function.
    So add it prior to the handler call:
    metalsToDel.sort()
    itemsLeft = deleteSubset(metals, metalsToDel)

Regards,

IFC Programming Consultant
http://www.chnexus.com/main.htm
Private mailto:[EMAIL PROTECTED]





[To remove yourself from this list, or to change to digest mode, go to
http://www.penworks.com/LUJ/lingo-l.cgi  To post messages to the list,
email [EMAIL PROTECTED]  (Problems, email [EMAIL PROTECTED])
Lingo-L is for learning and helping with programming Lingo.  Thanks!]

Reply via email to