Cool, looks like the implicit cast is faster across the board, and almost twice as fast as just using the array access operator.
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

