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