Sunday, January 23, 2011

With keyword speed test

One of the most rarely used keyword in ActionScript 3 is definitely the 'with' keyword. Let's see what the documentation tells us about this keyword:

Establishes a default object to be used for the execution of a statement or statements, potentially reducing the amount of code that needs to be written.

You read more about 'with' keyword in documentation.

This looks promising, we do love the "write less, do more" concept, but how about performance of this solution? I've tested it by comparing multiple this.graphics... calls and 'with' keyword shortcut syntax. Enough writing, let's see what I came up with:

private function withKeywordTest():void
{
  var initialTime:int;
  var time:int;
  var i:int;
  var t:int;
  const loopCount:int = 100000;
  const testsCount:int = 10;
  
  time = 0;
  for(t = 0; t < testsCount; t++)
  {
    initialTime = getTimer();
    for(i = 0; i < loopCount; i++)
    {
      with(this.graphics)
      {
        lineStyle(1);
        beginFill(0x000000);
        drawRect(0, 0, 10, 10);
        endFill();
        clear();
      }
    }
    time += getTimer() - initialTime;
  }
  log("With keyword: " + Math.round(time / testsCount) + "ms");
  
  time = 0;
  for(t = 0; t < testsCount; t++)
  {
    initialTime = getTimer();
    for(i = 0; i < loopCount; i++)
    {
      this.graphics.lineStyle(1);
      this.graphics.beginFill(0x000000);
      this.graphics.drawRect(0, 0, 10, 10);
      this.graphics.endFill();
      this.graphics.clear();
    }
    time += getTimer() - initialTime;
  }
  log("Code repetitions: " + Math.round(time / testsCount) + "ms");
}

The tests were taken 10 times each, ending result is a mean time in miliseconds:
Hardware with keyword code repetitions
2.1 Ghz Intel Core 2 Duo, Windows 7
Flash Player 10.1 Release
108ms 112ms
This test shows that using with keyword can be a little faster, but sometimes when I run this test it can be a little slower so I think there's no difference which code style you use. The real advantage of 'with' keyword is reduction of code repetitions like constantly writing this.graphics.
But as always, there is the other side of the coin - code within 'with' block isn't evaluated at compile time. That means if you change with(this.graphics) to with(this) in my example, the code will compile just fine - of course you'll get runtime error, but lack of compile time checking can be a problem. I would suggest using 'with' keyword for common actions like programmatic drawing and other kind of jobs that can't suprise you.

--- public static const UPDATE:String ---

A very kind man and a detective Jackson Dunstan gave me an advice to try to refine my tests using caching this.graphics getter value in a local variable. The idea was to show that 'with' block is in fact slower than normal code repetition. Here is refined test method:

private function withKeywordLocalVariableTest():void
{
   var initialTime:int;
   var time:int;
   var i:int;
   var t:int;
   const loopCount:int = 100000;
   const testsCount:int = 10;
   
   var g:Graphics = this.graphics;
   
   time = 0;
   for(t = 0; t < testsCount; t++)
   {
     initialTime = getTimer();
     for(i = 0; i < loopCount; i++)
     {
      with(g)
      {
       lineStyle(1);
       beginFill(0x000000);
       drawRect(0, 0, 10, 10);
       endFill();
       clear();
      }
     }
     time += getTimer() - initialTime;
   }
   log("With keyword(local variable): " + Math.round(time / testsCount) + "ms");
   
   time = 0;
   for(t = 0; t < testsCount; t++)
   {
     initialTime = getTimer();
     for(i = 0; i < loopCount; i++)
     {
      g.lineStyle(1);
      g.beginFill(0x000000);
      g.drawRect(0, 0, 10, 10);
      g.endFill();
      g.clear();
     }
     time += getTimer() - initialTime;
   }
   log("Normal this.graphics repetitions(local variable): " + Math.round(time / testsCount) + "ms");
}
Hardware with keyword (local variable) code repetitions (local variable)
2.1 Ghz Intel Core 2 Duo, Windows 7
Flash Player 10.1 Release
107ms 102ms

Those results using local variable caching in fact a little different. With keyword seems to be a slower solution. This definitely isn't bringing me closer to using 'with' keyword:)

3 komentarze:

Jackson Dunstan said...

It's good to see people interested in such esoteric areas of AS3 performance! :-D

I've written about some related articles about "with" block syntax, bytecode and performance before. My tests showed "with" to be about 6x slower than local variable access. Your test is using a getter field call (this.graphics), which is quite a bit slower than a local variable access. I think a fairer test would be to cache this.graphics as a local variable outside of the test loop and access the cached version instead. I'll bet you'll find the results radically different.

fastas3 said...

Thanks Jackson, it's good to see people reading this:D
Good point with getter, I'll try to run test with local variable caching and post update here. For now I can't convince myself to use "with" block on a regular basis, but I'm pretty sure it's great for rapid prototyping.

fastas3 said...

I've created 2nd test with local variable caching. You were right, "with" block seems to be slower but not as much as you've pointed out (6x).

Post a Comment

 
Powered by Blogger