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