20 Tips to Optimize your ActionScript

Introduction This article is primarily concerned with ActionScript 3 and generally specific to AVM2. Most suggestions would apply to ActionScript 2 as well, and I've noted those tips that differ between AS2 and AS3. With the advent of ActionScript 3.0 (hereafter "AS3"), the Flash Player realized significant performance gains. A few years ago, I ran some performance tests comparing JavaScript to AS2. ActionScript was noticably slower in every benchmark, usually in the range of 300% or more time required to perform large calculations. Even animation - Flash's wheelhouse - was slower. AVM2 and AS3 have changed that, and levelled the playing field to a large degree. That said, the greatest single contributor to slow performance of Flash applications is poorly written ActionScript. Below you'll find 20 tips to help you write faster applications. Please note that the motivation behind each tip is performance, not transparency or best practice. A performance optimization might directly oppose a best practice, and will very often create opacity in your code. It's your decision as to what takes priority in your application: performance, transparency or best practices. Much of the information presented here will provide only negligible gains as regards performance when used in small-scale code operations. However, when a developer tweens 3500 raindrops every frame, every line of code needs to be parsed and pared to the sharpest, smallest point possible. Before I begin, learn to benchmark your code. There are many approaches, including specialized software or components like frame-rate meters, but the simplest trick I know is to measure the time a loop containing the statements to be tested takes to operate. After all other setup is performed, on the line immediately before the loop, call the getTimer method and store it in a variable. Execute your loop (I usually start with 1000 iterations to avoid script timeout, then increase by a factor of 10 until I get a measurable metric). Immediately following the loop, evaulate the difference by invoking getTimer again and subtracting it from the first. E.g., var start:Number = getTimer(); for(var i:int=0;i<1000;i++){ // statements to evaluate } trace(start-getTimer()); 5: The Tips Multiple conditionals are faster than stacked operators When using stacked operators in an evaluation statement, each one is evaluated before returning the result. Using conditional statements allows the VM to stop checking as soon as it can - when further evaluation is no longer needed. if(var1) if(var2) if(var3) is faster than if(var1 && var2 && var3) Object literals are faster than the new operator Strings, Numbers (including int and uint), and Boolean objects are usually instantiated using literal notation (var str:String = "text"). Objects and Arrays are often instantiated using the "new" operator - this is seldom necessary (only in the case of a fixed-length Array), and is slower. var list:Array = [1,2,3]; is faster than var list:Array = new Array(1,2,3); For loops are faster than while and do-while loops In AS3, the fastest loop is the for loop (not for.. or for each..in). While and do-while are slightly slower. Note that this is a marked contrast to both ActionScript 2 and JavaScript, where while and do-while are about 3 times faster than for loops. Also, the int datatype is faster than uint or Number (see tip #16). for(var i:int=0;i<1000;i++) is faster than var i:int=0; while(i<1000) The in operator is faster than hasOwnProperty To test if an object has a publically available property, use the "in" operator instead of the hasOwnProperty method. prop in Object is faster than Object.hasOwnProperty("prop") 5: The one-dot rule When accessing nested variables, anytime a variable requires even one level of scope shift to discover, and is referenced more than once, save it to local variable. In drawing classes, you'll often see Math.PI / 2 referenced within loops that might iterated hundreds of times each frame - that value should be stored in a local variable. Note that this is not true when referencing member methods. Saving Math.PI to a variable is appropriate; saving Math.round to a variable is not. var var Number = container.child.x; textfield.text = var1; container.child2.x = var1; is faster than textfield.text = container.child.x; container.child2.x = container.child.x; 6: Dynamic classes are slow - use a public object variable instead Avoid dynamic classes. Consider a public variable datatyped to Object instead. public class MyObject{ public var variables:Object = {}; } is faster than public dynamic class MyObject{ } 7: Perform work in enterframes This one may seem counter-intuitive, and most tutorials and help-boards are peppered with warning against enter frames. Surprisingly, performing heavy calculation during the enterframe can help "balance the load" and lead to improved performance. 8: Standard string methods are faster than Regular Expressions Regular Expressions are a great tool and can make complex tasks much easier. However, standard string methods are almost always faster. var parts:Array = longString.split("|"); is faster than var parts:Array = longString.match(/(.*?)\|/gm); 9: Use plain text instead of XML where possible XML requires the VM to implement a parser, where evaluating plain text requires no special operation. Where possible, use strings or plain text rather than XML. 10: Work from the top of the stack When manipulating arrays, work is performed from the top-down. That means always work from the end of the array, rather than the beginning. Pop and push are faster than shift and unshift. MyArray.push(myVar); is faster than MyArray.shift(myVar); 1 enterFrames are faster than timers and intervals Flash handles enterFrames as part of it's native update process - timers and setInterval calls are not. Actions performed during the enterFrame event perform better than equally frequent Timer events. addEventListener("enterFrame",myFunc); is faster than myTimer.addEventListener("timer",myFunc); 1 Use local variables When flash detects a variable, it looks first at the local scope - the context of the currently evaluating function. If not found, it looks at the next "highest" scope, and repeats, until the variable is discovered (or undefined is returned). Always use local variables when possible. Note that function arguments are considered local variables. function getMinutes(){ var myVar:uint = 6000; return getTimer() / myVar; } is faster than var myVar:uint = 6000; function getMinutes(){ return getTimer() / myVar; } 1 Constants are faster than variables If a variable is unlikely to change, use the const declaration rather than the var declaration. const URL:String = "http://www.experts-exchange.com"; is faster than var URL:String = "http://www.experts-exchange.com"; 1 Use the as operator instead of casting Use the "as" operator when possible, instead of casting via constructor. var child:MyClass = event.currentTarget as MyClass; is faster than var child:MyClass = MyClass(event.currentTarget); 15: E4X is extremely slow E4X is another great tool that can offer drastic savings in development time, but when used on large data sets its performance tends to suffer. Surprisingly, looping through an XML tree is often much faster than complicated E4X structures. for each(var node:XML in myXML){ if(node.@myProp == "value"){ if(node.@anotherProp == 12){ react(); } } } 5: 6: 7: is faster than var nodes:XMLList = myXML.(@myProp=="value").(@anotherProp==12); for each(var node:XML in nodes){ react(); } 16: int - uint - Number Of the three Number datatypes, Number is the slowest, int is the fastest, and uint is slightly slower than int. This applies to simple evaluation only, such as when looping (always set the iterator to the int datatype). However, performance varies when using more complex evaluation - for example, division operations are performed more quickly on Numbers than ints or uints - I suspect this is because all numbers are cast as Number when performing division, because the return must contain the possibility of a float. for(var i:int=0;i<10000;i++) is faster than for(var i:Number=0;i<10000;i++) 17: Use bitwise methods when possible Figuring out the math behind bitwise operation can be intimidating, but there are simple ways to use bitwise functionality that can really speed up your code. var n:Number = 93745298347.230498; var m:Number = n|0; is faster than var n:Number = 93745298347.230498; var m:Number = Math.foor(n); 18: Use array.join instead of string concatenation String concatenation is very slow - use arrays and array methods where possible. var myArray:Array = []; for(var i:int=0;i<1000;i++){ myArray[i] = "text"; }; var myString:String = myArray.join(" "); 5: is faster than var myString:String = ""; for(var i:int=0;i<1000;i++){ myString += "text "; }; 19: Don't evaluate in a loop's conditional test The condition expression in the for loop is commonly used to evaluate a variable or property - this expression should be a predefined local variable when possible, so that it doesn't need to be evaluated during each iteration of the loop. var l:uint = myArray.length; for(var i:int=0;i

0

收藏

yoohoow

14篇文章,1W+人氣,0粉絲

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章