PD: To add to how accessing the last element in the array works, this is the
relevant bit:

      34    getlocal2
      35    getlocal2
      36    getproperty    length
      38    getlocal1
      39    setproperty    null


local2 is the array and local1 is the i variable:

So, considering this snippet as a self contained block regarding stack
state, breaking it down what happens is this:

   stack state
actionscript pseudo-equivalent
   34  theArray
   35  theArray, theArray
   36 theArray, theArray.length
   38 theArray, theArray.length, variable_i
   39 [empty]
theArray[theArray.length] = variable_i


Cheers
Juan Pablo Califano


2008/7/30, Juan Pablo Califano <[EMAIL PROTECTED]>:
>
> My undestanding is that push should be slower than accessing the index
> directly, but take that as "common sense": a function call should involve a
> bit more processing, but I don't know the specifics. I do know that both
> compiles to different bytecode. Off the top of my head, it was 4 ops,
> something like
>
> push value
> push index
> push theobject
> setproperty    ==> theobject[index] = value
>
> Making a push involves a callProperty operation, where you pass the object,
> the method and the arguments. Maybe it's the same number of operations, but
> I think the call operation is a bit more complex internally, as it creates a
> new frame on the stack, it has to pass the arguments, executes the function,
> clears the stack frame and then returns back to the callee.
>
> For disassembling, I'm using abcdump, a tool that is included in the
> Tamarin project. You can find a compiled version for Windows and use
> instructions here (though it's super easy to use):
>
>
> http://iteratif.free.fr/blog/index.php?2006/11/15/61-un-premier-decompileur-as3
> It's in french, but looking at the text added to your reply, I assume
> you'll have not problems with that ;)
>
> Another post about the subject, in English
> http://www.5etdemi.com/blog/archives/2007/01/as3-decompiler/
>
>
>
> Cheers
> Juan Pablo Califano
>
> 2008/7/30, laurent <[EMAIL PROTECTED]>:
>>
>> Hm yes, there's no difference between For and while.
>> What do you think about a[ a.length ] and a.push(); ?
>>
>> How did you get the decompiles function ?
>>
>> Thanks for pushing it.
>> L
>>
>> Juan Pablo Califano a écrit :
>>
>>> I'd take these results with a pinch of salt. I don't think they're
>>> conclusive, since one test seems to affect the performance of the others
>>> (and we are talking about really small differences anyway, which I think
>>> could be attributed to other factors than the tested code itself).
>>>
>>> Let's take, for instance the for / while tests. If I run all your tests,
>>> I
>>> get results similar to yours.
>>>
>>> takeLengthPlusOut : 1958
>>> takeForWithLengthPlus : 1788
>>>
>>> However, if I run just those two tests the results change. And if I alter
>>> the order in which the tests are run, the first one always seems to take
>>> less time.
>>> // running just these two, tracing the results in the same order the
>>> loops
>>> are executed
>>>
>>> takeLengthPlusOut : 1876
>>> takeForWithLengthPlus : 2003
>>>
>>> takeLengthPlusOut : 1876
>>> takeForWithLengthPlus : 1935
>>>
>>> takeForWithLengthPlus : 1874
>>> takeLengthPlusOut : 1946
>>>
>>> takeForWithLengthPlus : 1861
>>> takeLengthPlusOut : 1935
>>> I think this particular for / while case is very illustrative of some
>>> external bias, because the execution order consistently affects the
>>> results
>>> and because if you disassemble both loops, they're nearly identical. The
>>> only difference is the order in which one operation previous to the loop
>>> is
>>> executed (it's not even the "body" of the loop or its conditional test).
>>>
>>>
>>> FOR:
>>>
>>>    function takeForWithLengthPlus():String /* disp_id 0*/
>>>    {
>>>      // local_count=4 max_scope=1 max_stack=3 code_len=61
>>>      0     getlocal0
>>>      1     pushscope
>>>      2     pushbyte       0
>>>      4     setlocal1
>>>      5     pushnull
>>>      6     coerce         Array
>>>      8     setlocal2
>>>      9     pushnan
>>>      10    setlocal3
>>>      11    findpropstrict Array
>>>      13    constructprop  Array (0)
>>>      16    coerce         Array
>>>      18    setlocal2
>>>      19    findpropstrict flash.utils::getTimer
>>>      21    callproperty   flash.utils::getTimer (0)
>>>      24    convert_d
>>>      25    setlocal3
>>>      26    pushbyte       0
>>>      28    setlocal1
>>>      29    jump           L1
>>>
>>>
>>>      L2:
>>>      33    label
>>>      34    getlocal2
>>>      35    getlocal2
>>>      36    getproperty    length
>>>      38    getlocal1
>>>      39    setproperty    null
>>>      41    inclocal_i     1
>>>
>>>      L1:
>>>      43    getlocal1
>>>      44    pushint        10000000 // 0x989680
>>>      46    iflt           L2
>>>
>>>      50    pushstring     "takeForWithLengthPlus : "
>>>      52    findpropstrict flash.utils::getTimer
>>>      54    callproperty   flash.utils::getTimer (0)
>>>      57    getlocal3
>>>      58    subtract
>>>      59    add
>>>      60    returnvalue
>>>    }
>>>
>>>
>>> WHILE:
>>>
>>>    function takeLengthPlusOut():String /* disp_id 0*/
>>>    {
>>>      // local_count=4 max_scope=1 max_stack=3 code_len=61
>>>      0     getlocal0
>>>      1     pushscope
>>>      2     pushbyte       0
>>>      4     setlocal1
>>>      5     pushnull
>>>      6     coerce         Array
>>>      8     setlocal2
>>>      9     pushnan
>>>      10    setlocal3
>>>      11    pushbyte       0
>>>      13    setlocal1
>>>      14    findpropstrict Array
>>>      16    constructprop  Array (0)
>>>      19    coerce         Array
>>>      21    setlocal2
>>>      22    findpropstrict flash.utils::getTimer
>>>      24    callproperty   flash.utils::getTimer (0)
>>>      27    convert_d
>>>      28    setlocal3
>>>      29    jump           L1
>>>
>>>
>>>      L2:
>>>      33    label
>>>      34    getlocal2
>>>      35    getlocal2
>>>      36    getproperty    length
>>>      38    getlocal1
>>>      39    setproperty    null
>>>      41    inclocal_i     1
>>>
>>>      L1:
>>>      43    getlocal1
>>>      44    pushint        10000000 // 0x989680
>>>      46    iflt           L2
>>>
>>>      50    pushstring     "takeLengthPlusOut : "
>>>      52    findpropstrict flash.utils::getTimer
>>>      54    callproperty   flash.utils::getTimer (0)
>>>      57    getlocal3
>>>      58    subtract
>>>      59    add
>>>      60    returnvalue
>>>    }
>>> The only difference is that in the foor loop, i = 0 is run immediately
>>> before testing i against 10000000:
>>>
>>>      26    pushbyte       0
>>>      28    setlocal1
>>>
>>> whereas in the while loop, that assignment is executed before
>>> constructing
>>> the array:
>>>
>>>      11    pushbyte       0
>>>      13    setlocal1
>>>
>>>
>>> Cheers
>>> Juan Pablo Califano
>>>
>>> 2008/7/29, laurent <[EMAIL PROTECTED]>:
>>>
>>>
>>>> Hi,
>>>>
>>>> I often asked myself if a[ a.length ] = xxx was faster or slower then
>>>> a.push( xxx ), I did some test at wake up, fresh with coffee.
>>>> So now I know the answer and I got a bit more about while and for, and
>>>> more
>>>> obvious about using them with decremental or incremental counters.
>>>>
>>>> from results, > means faster :
>>>>
>>>> for > while ....hey yes...oO
>>>> increment > decrement
>>>> length > push
>>>> increment or certainly make any number operation at same time than
>>>> putting
>>>> the value in variable is slower than separate those actions, like:
>>>>  a[ a.length ] = i++;
>>>> slower than:
>>>>  i++;
>>>>  a[ a.length ] = i;
>>>>
>>>> "while incremental" is faster than "for decremental".
>>>> This is a totaly useless information as if you can use the while
>>>> incremental instead of For decremental, then just use For incremental.
>>>> I heard that any loop was compiled to a while loop so I started coding
>>>> everything with a while, what is faster to write and more elegant.
>>>> Now I'll go back to those For loops, I promess I never stoped loving you
>>>> guys...
>>>>
>>>> here some convincing results :
>>>> takeLengthMinus : 1695
>>>> takeLengthMinusOut : 1598
>>>> takeLengthPlus : 1580
>>>> takeLengthPlusOut : 1550
>>>>
>>>>
>>>> takePushMinus : 1860
>>>> takePushMinusOut : 1768
>>>> takePushPlus : 1756
>>>> takePushPlusOut : 1685
>>>>
>>>> Don't compare results between separate paragraphe because they did not
>>>> run
>>>> all together:
>>>>
>>>> takeForWithLengthMinus : 1624
>>>> takeForWithLengthPlus : 1581
>>>>
>>>> The For loop is directly with operation outside, so it has to be
>>>> compared
>>>> to the
>>>>
>>>> other outside operations:
>>>>
>>>> takeLengthMinusOut : 1686
>>>> takeLengthPlusOut : 1610
>>>> takePushMinusOut : 1788
>>>> takePushPlusOut : 1666
>>>> takeForWithLengthMinus : 1626
>>>> takeForWithLengthPlus : 1563
>>>>
>>>> I guess that's why I learned to use for( i = 0; i < n; i++ ) for my
>>>> first
>>>> loops.
>>>> So if we want our code faster we have to make it longer and actually
>>>> more
>>>> human readable, at the same time it means more computer readable as it
>>>> gets
>>>> faster....hm, is the computer so close to human...?!
>>>>
>>>> I [ mean my brain ] actually use a dicotomic way to find my current
>>>> client
>>>> folder in the list of all my works.
>>>>
>>>> cheers.
>>>> L
>>>>
>>>> and here the codes :
>>>>
>>>>
>>>> function takeLengthMinus():String{
>>>>  var i : int = 10000000;
>>>>  var a: Array = new Array();
>>>>  var t: Number = getTimer();
>>>>  while( i-- ){
>>>>      a[ a.length ] = i;
>>>>  }
>>>>  return "takeLengthMinus : " + ( getTimer() - t );
>>>> }
>>>>
>>>> function takeLengthMinusOut():String{
>>>>  var i : int = 10000000;
>>>>  var a: Array = new Array();
>>>>  var t: Number = getTimer();
>>>>  while( i ){
>>>>      a[ a.length ] = i;
>>>>      i--;
>>>>  }
>>>>  return "takeLengthMinusOut : " + ( getTimer() - t );
>>>> }
>>>>
>>>> function takeLengthPlus():String{
>>>>  var i : int = 0;
>>>>  var a: Array = new Array();
>>>>  var t: Number = getTimer();
>>>>  while( i < 10000000 ){
>>>>      a[ a.length ] = i++;
>>>>  }
>>>>  return "takeLengthPlus : " + ( getTimer() - t );
>>>> }
>>>>
>>>> function takeLengthPlusOut():String{
>>>>  var i : int = 0;
>>>>  var a: Array = new Array();
>>>>  var t: Number = getTimer();
>>>>  while( i < 10000000 ){
>>>>      a[ a.length ] = i;
>>>>      i++;
>>>>  }
>>>>  return "takeLengthPlusOut : " + ( getTimer() - t );
>>>> }
>>>>
>>>> function takePushMinus():String{
>>>>  var i : int = 10000000;
>>>>  var a: Array = new Array();
>>>>  var t: Number = getTimer();
>>>>  while( i-- ){
>>>>      a.push( i );
>>>>  }
>>>>  return "takePushMinus : " + ( getTimer() - t );
>>>> }
>>>>
>>>> function takePushMinusOut():String{
>>>>  var i : int = 10000000;
>>>>  var a: Array = new Array();
>>>>  var t: Number = getTimer();
>>>>  while( i ){
>>>>      i--;
>>>>      a.push( i );
>>>>  }
>>>>  return "takePushMinusOut : " + ( getTimer() - t );
>>>> }
>>>>
>>>> function takePushPlus():String{
>>>>  var i : int = 0;
>>>>  var a: Array = new Array();
>>>>  var t: Number = getTimer();
>>>>  while( i < 10000000 ){
>>>>      a.push( i++ );
>>>>  }
>>>>  return "takePushPlus : " + ( getTimer() - t );
>>>> }
>>>>
>>>> function takePushPlusOut():String{
>>>>  var i : int = 0;
>>>>  var a: Array = new Array();
>>>>  var t: Number = getTimer();
>>>>  while( i < 10000000 ){
>>>>      a.push( i );
>>>>      i++;
>>>>  }
>>>>  return "takePushPlusOut : " + ( getTimer() - t );
>>>> }
>>>>
>>>> function takeForWithLengthMinus():String{
>>>>  var i : int;
>>>>  var a: Array = new Array();
>>>>  var t: Number = getTimer();
>>>>  for( i = 10000000; i > 0; i-- ){
>>>>      a[ a.length ] = i;
>>>>  }
>>>>  return "takeForWithLengthMinus : " + ( getTimer() - t );
>>>> }
>>>>
>>>> function takeForWithLengthPlus():String{
>>>>  var i : int;
>>>>  var a: Array = new Array();
>>>>  var t: Number = getTimer();
>>>>  for( i = 0; i < 10000000; i++ ){
>>>>      a[ a.length ] = i;
>>>>  }
>>>>  return "takeForWithLengthPlus : " + ( getTimer() - t );
>>>> }
>>>>
>>>> //trace( takeLengthMinus() );
>>>> trace( takeLengthMinusOut() );
>>>> //trace( takeLengthPlus() );
>>>> trace( takeLengthPlusOut() );
>>>> //trace( takePushMinus() );
>>>> trace( takePushMinusOut() );
>>>> //trace( takePushPlus() );
>>>> trace( takePushPlusOut() );
>>>> trace( takeForWithLengthMinus() );
>>>> trace( takeForWithLengthPlus() );
>>>>
>>>> _______________________________________________
>>>> Flashcoders mailing list
>>>> Flashcoders@chattyfig.figleaf.com
>>>> http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
>>>>
>>>>
>>>>
>>> _______________________________________________
>>> Flashcoders mailing list
>>> Flashcoders@chattyfig.figleaf.com
>>> http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
>>>
>>>
>>> __________ Information from ESET NOD32 Antivirus, version of virus
>>> signature database 3309 (20080730) __________
>>>
>>> The message was checked by ESET NOD32 Antivirus.
>>>
>>> http://www.eset.com
>>>
>>>
>>>
>>>
>>>
>>
>> _______________________________________________
>> Flashcoders mailing list
>> Flashcoders@chattyfig.figleaf.com
>> http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
>>
>
>
_______________________________________________
Flashcoders mailing list
Flashcoders@chattyfig.figleaf.com
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

Reply via email to