Piers Cowburn wrote:
Cool, looks like the implicit cast is faster across the board, and almost twice 
as fast as just using the array access operator.
For an object of a known class, I think the compiler is just referring directly to the method rather than looking it up. When a method is invoked on an abstract object it has to look at the class info for the object to locate the method AT RUNTIME - hence the overhead. When the class is known it can call the method directly without a runtime lookup.

In the case of the explicit cast, I would expect that the cast is pointless and adding needless overhead since the method reference is using the method lookup at compile time from the variable, not from the cast. The cast adds needless overhead at run time.

Paul

On 27 Dec 2009, at 13:13, Cor wrote:

With this, my results are:
Starting tests...
[Array 0a] Array access test: 462
[Array 1a] Implicit cast test: 258
[Array 2a] Explicit cast test: 406
[Array 3a] As cast test: 429
[Array 0b] Array access test (two operations): 1062
[Array 1b] Implicit cast test (two operations): 477
[Array 2b] Explicit cast test (two operations): 647
[Array 3b] As cast test (two operations): 652
[Vector 0a] Vector access test: 458
[Vector 1a] Implicit cast test: 252
[Vector 2a] Explicit cast test: 402
[Vector 3a] As cast test: 425
[Vector 0b] Vector access test (two operations): 1034
[Vector 1b] Implicit cast test (two operations): 483
[Vector 2b] Explicit cast test (two operations): 624
[Vector 3b] As cast test (two operations): 679

-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Piers
Cowburn
Sent: zondag 27 december 2009 14:07
To: Flash Coders List
Subject: Re: [Flashcoders] Performance from casting array/vector?

Hi Cor,

This was my test class, just a couple of dummy methods that do a variable
declaration and an increment:

package { /**
    * Internal test class
    */
   public class TestClass
   {
       public function someMethod():void
       {
           var i:int = 0;
           i++;
       }

       public function someOtherMethod():void
       {
           var i:int = 0;
           i++;
       }
   }
}


Piers


On 27 Dec 2009, at 11:52, Cor wrote:

Hi piers,

I am trying to follow your topic.
What is in your TestClass.as??

Kind regards
Cor

-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Piers
Cowburn
Sent: zondag 27 december 2009 12:35
To: Flash Coders List
Subject: Re: [Flashcoders] Performance from casting array/vector?

Hi Steve,

I thought it'd be useful to have some actual figures, so I put together a
quick test. Test code was as follows:

package {
  import flash.display.Sprite;
import flash.utils.getTimer;
  /**
   * @author Piers Cowburn
   */
public class ArrayAccessTest extends Sprite {
      private const ITERATIONS:int = 1000000;

      public function ArrayAccessTest()
{ trace("Starting tests...");

          var startTimer:int;
          var i:int;
          var j:int;

          var array:Array = [new TestClass(), new TestClass(), new
TestClass()];
          var vector:Vector.<TestClass> = new Vector.<TestClass>();
          vector.push(new TestClass());
          vector.push(new TestClass());
          vector.push(new TestClass());
          var numItems:int = array.length;
          var implicitCast:TestClass;
          var explicitCast:TestClass;
          var asCast:TestClass;

          //
          // [Array 0a] Array access test
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                     array[j].someMethod();
              }
} trace("[Array 0a] Array access test: " +
(getTimer()-startTimer));

          //
          // [Array 1a] Implicit cast test
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                  implicitCast = array[j];
                     implicitCast.someMethod();
              }
} trace("[Array 1a] Implicit cast test: " +
(getTimer()-startTimer));

          //
          // [Array 2a] Explicit cast test
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                  explicitCast = TestClass(array[j]);
                     explicitCast.someMethod();
              }
} trace("[Array 2a] Explicit cast test: " +
(getTimer()-startTimer));

          //
          // [Array 3a] As cast test
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                  asCast = array[j] as TestClass;
                     asCast.someMethod();
              }
} trace("[Array 3a] As cast test: " + (getTimer()-startTimer));

          //
          // [Array 0b] Array access test (two operations)
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                     array[j].someMethod();
                     array[j].someOtherMethod();
              }
} trace("[Array 0b] Array access test (two operations): " +
(getTimer()-startTimer));

          //
          // [Array 1b] Implicit cast test (two operations)
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                  implicitCast = array[j];
                     implicitCast.someMethod();
                     implicitCast.someOtherMethod();
              }
} trace("[Array 1b] Implicit cast test (two operations): " +
(getTimer()-startTimer));

          //
          // [Array 2b] Explicit cast test (two operations)
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                  explicitCast = TestClass(array[j]);
                     explicitCast.someMethod();
                     explicitCast.someOtherMethod();
              }
} trace("[Array 2b] Explicit cast test (two operations): " +
(getTimer()-startTimer));

          //
          // [Array 3b] As cast test (two operations)
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                  asCast = array[j] as TestClass;
                     asCast.someMethod();
                     asCast.someOtherMethod();
              }
} trace("[Array 3b] As cast test (two operations): " +
(getTimer()-startTimer));



          //
          // [Vector 0a] Vector access test
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                     vector[j].someMethod();
              }
} trace("[Vector 0a] Vector access test: " +
(getTimer()-startTimer));

          //
          // [Vector 1a] Implicit cast test
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                  implicitCast = vector[j];
                     implicitCast.someMethod();
              }
} trace("[Vector 1a] Implicit cast test: " +
(getTimer()-startTimer));

          //
          // [Vector 2a] Explicit cast test
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                  explicitCast = TestClass(vector[j]);
                     explicitCast.someMethod();
              }
} trace("[Vector 2a] Explicit cast test: " +
(getTimer()-startTimer));

          //
          // [Vector 3a] As cast test
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                  asCast = vector[j] as TestClass;
                     asCast.someMethod();
              }
} trace("[Vector 3a] As cast test: " + (getTimer()-startTimer));


          //
          // [Vector 0b] Vector access test (two operations)
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                     vector[j].someMethod();
                     vector[j].someOtherMethod();
              }
} trace("[Vector 0b] Vector access test (two operations): " +
(getTimer()-startTimer));

          //
          // [Vector 1b] Implicit cast test (two operations)
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                  implicitCast = vector[j];
                     implicitCast.someMethod();
                     implicitCast.someOtherMethod();
              }
} trace("[Vector 1b] Implicit cast test (two operations): " +
(getTimer()-startTimer));

          //
          // [Vector 2b] Explicit cast test (two operations)
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                  explicitCast = TestClass(vector[j]);
                     explicitCast.someMethod();
                     explicitCast.someOtherMethod();
              }
} trace("[Vector 2b] Explicit cast test (two operations): " +
(getTimer()-startTimer));

          //
          // [Vector 3b] As cast test (two operations)
          startTimer = getTimer();
          for (i = 0; i < ITERATIONS; ++i)
          {
              for (j = 0; j < numItems; ++j)
              {
                  asCast = vector[j] as TestClass;
                     asCast.someMethod();
                     asCast.someOtherMethod();
              }
} trace("[Vector 3b] As cast test (two operations): " +
(getTimer()-startTimer));
      }
  }
}

And the results were:

[Array 0a] Array access test: 1631
[Array 1a] Implicit cast test: 1527
[Array 2a] Explicit cast test: 1689
[Array 3a] As cast test: 1745
[Array 0b] Array access test (two operations): 3172
[Array 1b] Implicit cast test (two operations): 2636
[Array 2b] Explicit cast test (two operations): 2817
[Array 3b] As cast test (two operations): 2841
[Vector 0a] Vector access test: 1624
[Vector 1a] Implicit cast test: 1520
[Vector 2a] Explicit cast test: 1707
[Vector 3a] As cast test: 1722
[Vector 0b] Vector access test (two operations): 3160
[Vector 1b] Implicit cast test (two operations): 2638
[Vector 2b] Explicit cast test (two operations): 2790
[Vector 3b] As cast test (two operations): 2828


I was surprised to see that using an implicit cast was fastest in all
situations, even faster than using the array access operator to make one
method call (test Array 0a vs. Array 1b). Also, you can see that storing a
temporary variable really starts to make a difference when you're making
more than one method call (difference between Array 0b and Array 1b).

HTH,
Piers


On 27 Dec 2009, at 01:26, Piers Cowburn wrote:

*Disclaimer* This is un-benchmarked, but it's what I usually work to! If
anyone has any corrections re. speed, I'd be glad to hear them :)
AFAIK, using implicit casting rather than explicit in this case is
faster,
so A1 in your examples is faster than A2. Also, it's better to move your
variable declaration outside the loop:
var i:int = myArray.length;
// Variable is declared once here and then reused
var myClass:MyClass;
while (i--)
{
myClass = myArray[i];
}


With vectors, you don't need to cast at all. However, though you can
access your references directly from the vector using [ ], like you've
done
in V3, it will be faster to store a local reference if you're using it
more
than once. So for example:
var i:int = myVector.length;
var myClass:MyClass;
while (i--)
{
// Store the reference in a temporary variable to avoid using [ ]
unnecessarily
myClass = myVector[i];
myClass.someMethod();
myClass.someOtherMethod();
}

will be faster than:

var i:int = myVector.length;
while (i--)
{
// This uses [ ] twice
myVector[i].someMethod();
myVector[i].someOtherMethod();
}


If you're only using the reference once though, it should be faster just
to use [ ], so:
var i:int = myVector.length;
while (i--)
{
// Just using the reference once, so not defining a temporary variable:
myVector[i].someMethod();
}

will be faster than:

var i:int = myVector.length;
var myClass:MyClass;
while (i--)
{
// This is a waste as we're only using it once
myClass = myVector[i];
myClass.someMethod();
}


As I said, I don't have benchmarked figures for these, so don't take it
as
gospel, but I think this was what I read when I read it.
Piers




On 27 Dec 2009, at 00:24, Steven Sacks wrote:

var instance1:MyClass = new MyClass();
var instance2:MyClass = new MyClass();
var instance3:MyClass = new MyClass();

var myArray:Array = [instance1, instance2, instance3];

// QUESTION A: CASTING WITH ARRAYS

var i:int = myArray.length;
while (i--)
{
// [A1] - Does Flash have to do a look up here?
var myClass:MyClass = myArray[i];

// [A2] - Does casting it like this boost performance
var myClass:MyClass = MyClass(myArray[i]);

// [A3] - I know using "as" is slower than direct casting
var myClass:MyClass = myArray[i] as MyClass;
}

// QUESTION B: CASTING WITH VECTORS

var myVector:Vector.<MyClass> = Vector.<MyClass>(myArray);

var i:int = myVector.length;

while (i--)
{
// [V1] - Will this avoid the lookup?
var myClass:MyClass = myVector[i];

// [V2] - Or do I need to cast here even though it's a Vector?
var myClass:MyClass = MyClass(myVector[i]);

// [V3] - And if so, can I do this without a lookup?
myVector[i].someMethod();

// [V4] - Or do I need to do this?
MyClass(myVector[i]).someMethod();
}


Thanks in advance for anyone who can shed some light here.  I believe
A2/V2 is "fastest" but I'm not certain, and I also don't know if it's
required for Vector.
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
No virus found in this incoming message.
Checked by AVG - www.avg.com Version: 9.0.722 / Virus Database: 270.14.119/2586 - Release Date:
12/26/09
20:02:00

_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
No virus found in this incoming message.
Checked by AVG - www.avg.com Version: 9.0.722 / Virus Database: 270.14.120/2588 - Release Date: 12/26/09
20:02:00

_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders


_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders


_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders

Reply via email to