PD: I have made some tests and it seems like using nested loops is much more
faster than using modulo + floor or modulo + int cast.

The results shows that while the elapsed time in nested loops tends to grow
linearly, when using modulo tends to grow exponentially. It shouldn't be a
problem with a small number of rows/cols, though.

The results:

100 rows x 100 cols
    rowFloor:2
    rowIntCast:1
    rowNestedLoops:0

500 rows x 500 cols
    rowFloor:78
    rowIntCast:27
    rowNestedLoops:1

1000 rows x 1000 cols
    rowFloor:287
    rowIntCast:96
    rowNestedLoops:4

2500 rows x 2500 cols
    rowFloor:1822
    rowIntCast:608
    rowNestedLoops:18

The tested code:

package {

 import flash.utils.getTimer;

 public class Rowing {

  private var rows:int = 500;
  private var cols:int = 500;


  public function Rowing() {
  }

  public function rowFloor():int {
   var init:int = getTimer();
   var len:int = rows * cols;

   var i:int = 0;
   var r:int = 0;
   var c:int = 0;

      for (i=0; i < len; i++) {
      c = i % cols;
     r = Math.floor(i/cols);
   // trace("c:"+c+"|r:"+r);
   }

   return getTimer() - init;
  }

  public function rowIntCast():int {
   var init:int = getTimer();
   var len:int = rows * cols;

   var i:int = 0;
   var r:int = 0;
   var c:int = 0;

      for (i=0; i < len; i++) {
      c = i % cols;
     r = int(i/cols);
   // trace("c:"+c+"|r:"+r);
   }

   return getTimer() - init;
  }


  public function rowNestedLoops():int {
   var init:int = getTimer();

   var r:int = 0;
   var c:int = 0;

   for(r = 0; r < rows; r++) {
    for(c = 0; c < cols; c++) {
    // trace("c:"+c+"|r:"+r);
    }
   }

   return getTimer() - init;
  }
 }
}

Cheers
Juan Pablo Califano



2008/5/25, Juan Pablo Califano <[EMAIL PROTECTED]>:
>
> I probably would, if it just were a superb compiler instead of a
> nice language (but incompatible at source level with AS) and a superb
> compiler ;)
>
> And if I were writting performance-critical suff (which I'm not), I'd
> certainly consider using it for building external swf libraries.
>
> Cheers
> Juan Pablo Califano
>
>
>
> 2008/5/25, laurent <[EMAIL PROTECTED]>:
>>
>> Yes. And you can jump to Haxe ;)
>>
>> cheers
>> L
>>
>> Juan Pablo Califano a écrit :
>>
>>> Thanks for the link.
>>>
>>> It seems clear from the tests that Math.floor *is* slower than casting.
>>> It
>>> think the implementation posted in the blog has a bug, though. The result
>>> of
>>> casting to int is the same as using Math.floor as long as the int is
>>> positive. But, if the int is negative, the results will be different.
>>>
>>> function testFloor():void {
>>>    var num:Number = -1.5;
>>>    var res:int = Math.floor(num);
>>>    trace("testFloor:"+res);  // traces -2
>>> }
>>> function testCast():void {
>>>    var num:Number = -1.5;
>>>    var res:int = int(num);
>>>    trace("testCast:"+res);  // traces -1
>>> }
>>>
>>> Maybe that's the reason why the compiler doesn't replace a call to
>>> Math.floor with a simple cast...
>>>
>>> Anyway, my point is that there are many layers under the actionscript
>>> code
>>> and the compiler could be making some optimizations you're normally not
>>> aware of. I've checked compiling and the decompiling the above functions
>>> to
>>> the assembly "il" representation (with abcdump). No such optimizations
>>> are
>>> made, so you're right about this.
>>>
>>> Nevertheless, I think some optimizations could be done (and maybe will
>>> be,
>>> some day?) on the compiler, like, for instance, inlining calls to
>>> Math.floor
>>> with code that would look like this, if it were Actionscript:
>>>
>>> Math.floor(num);
>>>
>>> -->
>>>
>>> num > 0 ? int(num) : int(num) - 1;
>>>
>>>
>>> Cheers
>>> Juan Pablo Califano
>>>
>>>
>>>
>>>
>>> 2008/5/25, laurent <[EMAIL PROTECTED]>:
>>>
>>>
>>>> John Grden wrote a post about many Math optimisations in AS3, you can
>>>> find
>>>> the code to test at home here:
>>>>
>>>> http://www.rockonflash.com/blog/?p=63
>>>>
>>>> L
>>>>
>>>> Juan Pablo Califano a écrit :
>>>>
>>>>
>>>>
>>>>> I use modulo for rowing too and int() instead of Math.floor() as it's
>>>>>
>>>>>
>>>>>> faster. ;)
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> Laurent,
>>>>>
>>>>> is it, really?
>>>>>
>>>>> I'm not sure. I recently made similar assumptions about what's faster
>>>>> an
>>>>> what's slower based on what "made sense", only to be proved wrong by
>>>>> some
>>>>> actual benchmarking.
>>>>>
>>>>> Anyway, if the variable is typed as an int, my understanding is that
>>>>> you
>>>>> don't need to use Math.floor or a cast to int, since the decimal part
>>>>> will
>>>>> be truncated automatically.
>>>>>
>>>>> Another option to discard decimals is to use bit shifting ( i >> 0),
>>>>> which
>>>>> some people say it's faster. But in the end, how do you know that under
>>>>> the
>>>>> hood, the flash player is not doing exactly the same operation for an
>>>>> int
>>>>> cast, a Math.floor call and a shift zero ?
>>>>>
>>>>> Cheers
>>>>> Juan Pablo Califano
>>>>>
>>>>>
>>>>> 2008/5/25, laurent <[EMAIL PROTECTED]>:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> Thanks Jesse for the neat explanation, it all make sense, that's a
>>>>>> clever
>>>>>> trick to get a smooth movement of this type where tweening is not a
>>>>>> solution.
>>>>>> That can be applied to other things just to get the right value to
>>>>>> change.
>>>>>> Very good to know that enter Frame and Timer are approximations.
>>>>>> I use modulo for rowing too and int() instead of Math.floor() as it's
>>>>>> faster. ;)
>>>>>>
>>>>>> L
>>>>>>
>>>>>> Jesse Graupmann a écrit :
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> @Laurent
>>>>>>>
>>>>>>> So modulus is great and slow from what I've read. I tend to use it in
>>>>>>> row/
>>>>>>> column calculation rather than wrapping a MovieClip position.
>>>>>>>
>>>>>>> var num:int = 6;
>>>>>>> var cols:int = 3;
>>>>>>>
>>>>>>> for ( var i:int = 0; i < num; i++ ) {
>>>>>>>      var row:int = Math.floor( i / cols );
>>>>>>>      var col:int = i % cols;
>>>>>>>
>>>>>>>      trace ( "i: " + i + "\trow:" + row + "\tcol:" + col );
>>>>>>> }
>>>>>>>
>>>>>>> i: 0    row:0   col:0
>>>>>>> i: 1    row:0   col:1
>>>>>>> i: 2    row:0   col:2
>>>>>>> i: 3    row:1   col:0
>>>>>>> i: 4    row:1   col:1
>>>>>>> i: 5    row:1   col:2
>>>>>>>
>>>>>>>
>>>>>>> In the previous post I'm moving a MovieClip to the right X.X pixels
>>>>>>> and
>>>>>>> when
>>>>>>> its position is off the screen I reset it back to 0. If I used the
>>>>>>> modulus
>>>>>>> method, the movement would always be rounded numbers and appear
>>>>>>> jerkier
>>>>>>> than
>>>>>>> this experiment requires. I'm actually hoping to round to the nearest
>>>>>>> twip.
>>>>>>>
>>>>>>>
>>>>>>> As for the examples themselves....
>>>>>>>
>>>>>>>
>>>>>>> #1
>>>>>>> onT is a timer tick. So about every 30ms it will move the MovieClip X
>>>>>>> pixels
>>>>>>> based on speed. Because Timers are never accurate to what you expect
>>>>>>> (
>>>>>>> they
>>>>>>> only get as close as they can - see below ) onT will always be
>>>>>>> dragging
>>>>>>> behind the other two methods and moving at varied speeds.
>>>>>>>
>>>>>>> //      Elapsed time from a tick on var t:Timer = new Timer(30);
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 47,38,36,36,36,36,36,38,36,35,35,36,36,34,36,42,36,35,35,36,35,37,40,36,36,3
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 6,36,36,54,36,37,35,34,36,38,38,36,36,36,36,69,39,35,36,35,36,36,42,44,36,36
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> ,35,36,35,63,37,33,36,35,37,40,30,35,34,36,92,55,66,35,36,34,36,46,36,36,36,
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 36,97,50,34,35,35,36,36,34,33,218,142,49,121,59,110,84,102,65,106,66,58,55,6
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 5,34,36,35,36,64,33,35,36,35,37,31,48,34,36,35,35,36,77,34,34,36,36,36,70,36
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> ,35,37,35,37,74,54,35,36,71,65,35,36,36,35,35,73,37,36,36,34,43,66,35,38,36,
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 35,34,73,36,34,50,59,67,37,36,36,36,56,47,37,36,36,34,36,30,46,35,36,36,36,5
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 9,46,35,36,36,36,59,45,35,36,36,34,36,32,48,37,37,35,38,56,48,34,36,36,36,58
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> ,47,34,37,36,36,57,72,45,36,50,55,45,35,35,35,36,61,45,36,35,35,36,66,45,131
>>>>>>>
>>>>>>> ,39,45,33,37,34,37,34,45,51,36,51,49,38,67,35,36,36,34,43,47,38,50,35,34
>>>>>>>
>>>>>>> //      Difference from expected 30ms
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 17,8,6,6,6,6,6,8,6,5,5,6,6,4,6,12,6,5,5,6,5,7,10,6,6,6,6,6,24,6,7,5,4,6,8,8,
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 6,6,6,6,39,9,5,6,5,6,6,12,14,6,6,5,6,5,33,7,3,6,5,7,10,0,5,4,6,62,25,36,5,6,
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 4,6,16,6,6,6,6,67,20,4,5,5,6,6,4,3,188,112,19,91,29,80,54,72,35,76,36,28,25,
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 35,4,6,5,6,34,3,5,6,5,7,1,18,4,6,5,5,6,47,4,4,6,6,6,40,6,5,7,5,7,44,24,5,6,4
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 1,35,5,6,6,5,5,43,7,6,6,4,13,36,5,8,6,5,4,43,6,4,20,29,37,7,6,6,6,26,17,7,6,
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 6,4,6,0,16,5,6,6,6,29,16,5,6,6,6,29,15,5,6,6,4,6,2,18,7,7,5,8,26,18,4,6,6,6,
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 28,17,4,7,6,6,27,42,15,6,20,25,15,5,5,5,6,31,15,6,5,5,6,36,15,101,9,15,3,7,4
>>>>>>> ,7,4,15,21,6,21,19,8,37,5,6,6,4,13,17,8,20,5,4
>>>>>>>
>>>>>>>
>>>>>>> #2
>>>>>>> onT2 - To compensate for the difference, I decide that for every 30ms
>>>>>>> that
>>>>>>> have passed the MovieClip should increment the correct amount ( 1
>>>>>>> pixel
>>>>>>> ).
>>>>>>> When the tick occurs, I subtract the stored time (lastTick2) from the
>>>>>>> current time giving me the most accurate elapsed time. Dividing by
>>>>>>> the
>>>>>>> tick
>>>>>>> time gives me a percentage of my expected elapsed time. Multiplying
>>>>>>> that
>>>>>>> value by the speed produces the most accurate change over time.
>>>>>>>
>>>>>>> #3
>>>>>>> onT3 - Because I can assume speed based on elapsed time is the most
>>>>>>> accurate, it won't matter when I call the function as long as it
>>>>>>> happens
>>>>>>> once per frame. So onT3 just uses the ENTER_FRAME event to calculate
>>>>>>> speed
>>>>>>> based on elapsed time using lastTick3.
>>>>>>>
>>>>>>> Here is another example that is commented a bit better and should
>>>>>>> make
>>>>>>> all
>>>>>>> this very apparent.
>>>>>>>
>>>>>>> stage.align = "TL";
>>>>>>> stage.scaleMode = "noScale";
>>>>>>> stage.addEventListener ( Event.ENTER_FRAME, onFrame );
>>>>>>>
>>>>>>> //      for every (stepTime)ms move (stepRate)pixels
>>>>>>> var stepTime:int = 30; var stepRate:int = 1;
>>>>>>> var time:int = getTimer();
>>>>>>>
>>>>>>> function onFrame ( e:Event ):void {
>>>>>>>      //      time since last frame
>>>>>>>      var elapsedTime:int = getTimer() - time;
>>>>>>>
>>>>>>>      //      store current time for the next check
>>>>>>>      time = getTimer();
>>>>>>>
>>>>>>>      //      percentage of expected time
>>>>>>>      var timePercentage:Number = elapsedTime / stepTime;
>>>>>>>
>>>>>>>      //      rate compensation
>>>>>>>      var movement:Number = timePercentage * stepRate;
>>>>>>>
>>>>>>>      //      move mc
>>>>>>>      mc.x += movement;
>>>>>>>
>>>>>>>      //      wrap if off the stage
>>>>>>>      if ( mc.x > stage.stageWidth ) mc.x = 0;
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> Hasta!
>>>>>>> Jesse
>>>>>>>
>>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: [EMAIL PROTECTED]
>>>>>>> [mailto:[EMAIL PROTECTED] On Behalf Of
>>>>>>> laurent
>>>>>>> Sent: Saturday, May 24, 2008 2:13 AM
>>>>>>> To: Flash Coders List
>>>>>>> Subject: Re: [Flashcoders] Tweening text more smoothly - AS3
>>>>>>>
>>>>>>>
>>>>>>> :) I just read about wraping using modulus on Grant Skinner's blog:
>>>>>>>
>>>>>>> sprite.x = (sprite.x + 5) % stage.stageWidth;
>>>>>>>
>>>>>>> And then get where was that checkWrap methods :]
>>>>>>> Still I'm interested in the onT methods...I don't think I will get
>>>>>>> them
>>>>>>> before Grant's next post.
>>>>>>>
>>>>>>> the article about using modulus:
>>>>>>> http://www.gskinner.com/blog/archives/2008/05/core_as3_modulu.html
>>>>>>>
>>>>>>>  L
>>>>>>>
>>>>>>> Jesse Graupmann a écrit :
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> Maybe converting the actual time elapsed to a constant rate of
>>>>>>>> motion
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>> could
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> help... who knows?
>>>>>>>>
>>>>>>>>
>>>>>>>> stage.align = "TL";
>>>>>>>> stage.scaleMode = "noScale";
>>>>>>>>
>>>>>>>> function checkWrap ( o:DisplayObject ):void
>>>>>>>> {
>>>>>>>>      if ( o.x > stage.stageWidth ) o.x = 0;
>>>>>>>> }
>>>>>>>>
>>>>>>>> var speed:Number = 1;
>>>>>>>> var tick:Number = 30;
>>>>>>>> var lastTick2:Number = getTimer();
>>>>>>>> var lastTick3:Number = getTimer();
>>>>>>>> var t:Timer = new Timer(tick);
>>>>>>>> var t2:Timer = new Timer(tick);
>>>>>>>>
>>>>>>>> t.addEventListener( TimerEvent.TIMER, onT );
>>>>>>>> t2.addEventListener( TimerEvent.TIMER, onT2 );
>>>>>>>> stage.addEventListener( Event.ENTER_FRAME, onT3 );
>>>>>>>> t.start();
>>>>>>>> t2.start();
>>>>>>>>
>>>>>>>>
>>>>>>>> function onT( e:TimerEvent ):void
>>>>>>>> {
>>>>>>>>      //      timer
>>>>>>>>      mc.x += speed;
>>>>>>>>      checkWrap ( mc );
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>> function onT2( e:TimerEvent ):void
>>>>>>>> {
>>>>>>>>      //      timer + speed
>>>>>>>>      mc2.x += (( getTimer() - lastTick2 ) / tick ) * speed;
>>>>>>>>      lastTick2 = getTimer();
>>>>>>>>      checkWrap ( mc2 );
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>> function onT3( e:Event ):void
>>>>>>>> {
>>>>>>>>      //      enter frame + speed
>>>>>>>>      mc3.x += (( getTimer() - lastTick3 ) / tick ) * speed;
>>>>>>>>      lastTick3 = getTimer();
>>>>>>>>      checkWrap ( mc3 );
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> 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
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> _______________________________________________
>>>>> 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
>>>>
>>>>
>>>>
>>> _______________________________________________
>>> 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
>>
>
>
_______________________________________________
Flashcoders mailing list
Flashcoders@chattyfig.figleaf.com
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

Reply via email to