On 7/25/06, Steven Sacks | BLITZ <[EMAIL PROTECTED]> wrote:
Oh, I just noticed that Mark's was fastest.  But, I can't get it to work
(freezes flash) There seems to be an error in the final while loop.
It's a single = not a double ==.  Is that a typo?

No, not a typo. I know it's confusing, but since this is about speed...
'list' is the current array. Say we have array A containing array B.
'list' is A and we iterate through it. At some point, we come across
B, so the current index gets stored away in A.index, A itself is
stored as B.parent, B gets assigned to 'list' and index reset to
iterate through B. Once we're at the end of B, we continue where we
left off in A (B.parent == list.parent at this point). However, the
inArray we want to flatten is the outermost array and has no parent --
when it's finished the loop ends.

Put differently, it would have been possible to write it like this:

do {
  // ...
  list = list.parent;
} while ( list != undefined );

Better readable, but oh so slightly slower...

If you want to use it for a library, though, there would be some
changes required. Out of laziness I stored the index and parent as a
property of the array. You wouldn't want that in a library, especially
not with such common names. One way would of course be to hide it with
AsSetPropFlags, but a stack would be better.
Unless you have a ridiculously deep recursion depth, you could even
use the VM's stack directly. That would save some getMembers and you
could do some additional optimizations while you're at it.
Disadvantage would be that you'd have to do it in flasm, obviously.
I tested this option, it shaves off a few percent (depending on
recursion depth between, say, 1% and 5%), is nowhere near finished,
only almost-not tested, to be used at your own risk and so on, but
could quite possibly be improved further. Oh, and it needs proper
register and variable names -- sorry.

   function2 (r:2='inArray') (r:1='this')
        // begin init
                // declare 'outArray'
     push 0
     initArray
     setRegister r:3
     pop

                // put 'null' on stack to mark end
     push NULL

                // push 'length' of 'inArray' and 'index' of 0 on
                // stack, followed by 'inArray'
     push r:inArray, 'length'
     getMember
     push 0, r:2

                // stack now looks like this:
                // NULL, inArray.length, 0, inArray
        // end init

     branch label2

                // check if something (should be an array) is on the
                // stack, otherwise it's NULL and we're done
    label1:

     dup
     not
     branchIfTrue label7

                // begin new loop: next array on stack
   label2:


                // take sub-array from stack
     setRegister r:4
     pop

                // take 'index' from stack
     setRegister r:6
     pop
                // take 'length' from stack
                
     setRegister r:7
     pop

                // begin new loop: loop through current array
    label3:

                // condition: (index < length)
     push r:6, r:7
     lessThan
     not
     branchIfTrue label1

     push r:4, r:6, r:6 // stack: array, index, index
     increment                  // index++
     setRegister r:6
     pop

                // get array[ index ] (i.e., 'item')
     getMember
     setRegister r:5

                // condition: ('item' instanceof 'Array')
     push 'Array'
     getVariable
     instanceOf
     not
     branchIfTrue label4

                // 'item' is an array
                // put length, index and current array on stack
     push r:7, r:6, r:4

                // put new current array on stack and into register
     push r:5
     setRegister r:4

                // get length and store in register
     push 'length'
     getMember
     setRegister r:7
     pop

                // set 'index' to 0
     push 0
     setRegister r:6
     pop

                // continue with new array
     branch label3

                // 'item' is no array
    label4:

                // append 'item' to 'outArray'
     push r:5, 1, r:3, 'push'
     callMethod
     pop
     branch label3

                // done going through the array
    label7:
                // remove NULL from stack
     pop

                // return 'outArray'
     push r:3
     return
   end // of function


Mark
_______________________________________________
[email protected]
To change your subscription options or search the archive:
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

Brought to you by Fig Leaf Software
Premier Authorized Adobe Consulting and Training
http://www.figleaf.com
http://training.figleaf.com

Reply via email to