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