Yeah, I was thinking along those lines. However, it's interesting that in tests 
Vector 0a vs Vector 1a, the implicit cast is still faster than using [ ] to 
access the reference directly from the vector. You'd think that with the vector 
being typed as TestClass, vector[i].someMethod() should be faster than var 
reference:TestClass = vector[i]; reference.someMethod()

Unless you were then going to use the reference again, in which case storing a 
temporary reference will always be faster. But for a one time look up from a 
typed vector, I'm surprised that two lines of code executes faster than one. I 
was wondering whether there might be something wrong with my test, but I can't 
see anything.

Piers



On 27 Dec 2009, at 14:05, Paul Andrews wrote:

> 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


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

Reply via email to