actionscript_优化ActionScript的20条技巧

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.

本文主要关注ActionScript 3,并且通常特定于AVM2。 大多数建议也适用于ActionScript 2,并且我注意到AS2和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.

随着ActionScript 3.0(以下称为“ AS3”)的出现,Flash Player实现了显着的性能提升。 几年前,我进行了一些性能测试,将JavaScript与AS2进行了比较。 值得注意的是,ActionScript在每个基准测试中都比较慢,通常在执行大型计算所需的时间在300%或更多的范围内。 甚至动画(Flash的操舵室)也较慢。 AVM2和AS3改变了这一点,并在很大程度上平衡了竞争环境。

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.

就是说,造成Flash应用程序性能下降的最大原因是ActionScript编写得不好。 您可以在下面找到20条提示,以帮助您编写更快的应用程序。 请注意,每个提示背后的动机是性能,而不是透明度或最佳实践。 性能优化可能直接反对最佳实践,并且通常会在代码中造成不透明性。 您要决定应用程序中的优先级:性能,透明度或最佳做法。

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.

当在小规模代码操作中使用时,此处提供的许多信息在性能方面的收益仅微不足道。 但是,当开发人员在每帧补间3500个雨滴时,需要解析每行代码并将其解析到尽可能最锐利的最小点。

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.,

在开始之前,请学习对代码进行基准测试。 有很多方法,包括专用软件或诸如帧率计之类的组件,但是我知道的最简单的窍门是测量包含要测试的语句的循环的运行时间。 完成所有其他设置后,在循环之前的那一行,调用getTimer方法并将其存储在变量中。 执行您的循环(我通常从1000次迭代开始,以避免脚本超时,然后增加10倍,直到获得可度量的指标)。 紧随循环之后,通过再次调用getTimer并从第一个减去getTimer来消除差异。 例如,

var start:Number = getTimer();
for(var i:int=0;i<1000;i++){
  // statements to evaluate
}
trace(start-getTimer());

The Tips

秘诀

1: Multiple conditionals are faster than stacked operators

1:多重条件比堆叠运算符更快

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.

在评估语句中使用堆叠式运算符时,将在返回结果之前对每个运算符进行评估。 使用条件语句可以使VM在不再需要进一步评估时尽快停止检查。

if(var1) if(var2) if(var3)
if(var1 && var2 && var3)

2: Object literals are faster than the new operator

2:对象文字比新运算符更快

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.

字符串,数字(包括int和uint)和布尔对象通常使用文字符号(var str:String =“ text”)实例化。 对象和数组通常使用“新”运算符实例化-很少需要(仅在固定长度数组的情况下),并且速度较慢。

var list:Array = [1,2,3];
var list:Array = new Array(1,2,3);

3: For loops are faster than while and do-while loops

3:for循环比while和do-while循环更快

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).

在AS3中,最快的循环是for循环(不是for ..或for..in)。 While和Do-while稍慢一些。 请注意,这与ActionScript 2和JavaScript明显不同,而while和do-while的速度大约是for循环的3倍。 同样,int数据类型比uint或Number更快(请参见技巧16)。

for(var i:int=0;i<1000;i++)
var i:int=0;
while(i<1000)

4: The in operator is faster than hasOwnProperty

4:in运算符比hasOwnProperty快

To test if an object has a publically available property, use the "in" operator instead of the hasOwnProperty method.

要测试对象是否具有公共可用的属性,请使用“ in”运算符而不是hasOwnProperty方法。

prop in Object
Object.hasOwnProperty("prop")

5: The one-dot rule

5:单点规则

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.

当访问嵌套变量时,任何时候只要一个变量甚至需要进行一级范围的移动才能发现,并且多次引用该变量,就将其保存到局部变量中。 在图形类中,您经常会看到在循环中引用的Math.PI / 2,该循环可能每帧迭代数百次-该值应存储在局部变量中。 请注意,引用成员方法时,情况并非如此。 将Math.PI保存到变量是合适的; 保存Math.round到一个变量不是。

var var1:Number = container.child.x;
textfield.text = var1;
container.child2.x = var1;
textfield.text = container.child.x;
container.child2.x = container.child.x;

6: Dynamic classes are slow - use a public object variable instead

6:动态类运行缓慢-请改用公共对象变量

Avoid dynamic classes.  Consider a public variable datatyped to Object instead.

避免动态类。 考虑将数据类型改为Object的公共变量。

public class MyObject{
  public var variables:Object = {};
}
public dynamic class MyObject{
}

7: Perform work in enterframes

7:在Enterframe中执行工作

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.

这可能看起来违反直觉,并且大多数教程和帮助面板都带有警告,禁止输入框。 出乎意料的是,在Enterframe期间执行大量计算可以帮助“平衡负载”并提高性能。

8: Standard string methods are faster than Regular Expressions

8:标准字符串方法比正则表达式更快

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("|");
var parts:Array = longString.match(/(.*?)\|/gm);

9: Use plain text instead of XML where possible

9:尽可能使用纯文本而不是XML

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.

XML需要VM来实现解析器,其中评估纯文本不需要任何特殊操作。 尽可能使用字符串或纯文本而不是XML。

10: Work from the top of the stack

10:从堆栈顶部开始

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);
MyArray.shift(myVar);

11: enterFrames are faster than timers and intervals

11:enterFrame比计时器和间隔更快

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.

Flash将EnterFrames作为其本机更新过程的一部分进行处理-计时器和setInterval调用则不是。 在enterFrame事件期间执行的操作要比同等频繁的Timer事件执行得更好。

addEventListener("enterFrame",myFunc);
myTimer.addEventListener("timer",myFunc);

12: Use local variables

12:使用局部变量

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.

当flash检测到变量时,它将首先查看局部范围-当前评估函数的上下文。 如果未找到,它将查看下一个“最高”作用域,然后重复进行直到发现变量(或返回未定义)。 尽可能使用局部变量。 请注意,函数参数被视为局部变量。

function getMinutes(){
  var myVar:uint = 6000;
  return getTimer() / myVar;
}
var myVar:uint = 6000;
function getMinutes(){
  return getTimer() / myVar;
}

13: Constants are faster than variables

13:常量比变量快

If a variable is unlikely to change, use the const declaration rather than the var declaration.

如果变量不太可能更改,请使用const声明而不是var声明。

const URL:String = "http://www.experts-exchange.com";
var URL:String = "http://www.experts-exchange.com";

14: Use the as operator instead of casting

14:使用as运算符代替强制转换

Use the "as" operator when possible, instead of casting via constructor.

尽可能使用“ as”运算符,而不是通过构造函数进行强制转换。

var child:MyClass = event.currentTarget as MyClass;
var child:MyClass = MyClass(event.currentTarget);

15: E4X is extremely slow

15:E4X非常慢

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.

E4X是另一种很棒的工具,可以大大节省开发时间,但是当用于大型数据集时,其性能往往会受到影响。 令人惊讶的是,遍历XML树通常比复杂的E4X结构要快得多。

for each(var node:XML in myXML){
  if(node.@myProp == "value"){
    if(node.@anotherProp == 12){
      react();
    }
  }
}
var nodes:XMLList = myXML.(@myProp=="value").(@anotherProp==12);
for each(var node:XML in nodes){
  react();
}

16: int - uint - Number

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.

在这三个Number数据类型中,Number是最慢的,int是最快的,而uint则比int稍慢。 这仅适用于简单评估,例如在循环时(始终将迭代器设置为int数据类型)。 但是,使用更复杂的求值时性​​能会有所不同-例如,对Numbers进行除法运算要比对ints或uints进行运算更快-我怀疑这是因为在执行除法运算时,所有数字都被强制转换为Number,因为返回值必须包含浮动。

for(var i:int=0;i<10000;i++)
for(var i:Number=0;i<10000;i++)

17: Use bitwise methods when possible

17:尽可能使用按位方法

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;
var n:Number = 93745298347.230498;
var m:Number = Math.foor(n);

18: Use array.join instead of string concatenation

18:使用array.join代替字符串连接

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(" ");
var myString:String = "";
for(var i:int=0;i<1000;i++){
  myString += "text ";
};

19: Don't evaluate in a loop's conditional test

19:不要在循环的条件测试中求值

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.

for循环中的条件表达式通常用于评估变量或属性-该表达式在可能的情况下应为预定义的局部变量,这样就不必在循环的每次迭代中对其进行评估。

var l:uint = myArray.length;
for(var i:int=0;i<l;i++)
for(var i:int=0;i<myArray.length;i++)

20: Use static methods where possible

20:尽可能使用静态方法

Static members are created once, and are not copied to instances.

静态成员仅创建一次,并且不会复制到实例。

private static function myFunc():void{};
private function myFunc():void{};

Conclusion

结论

I hope the tips I've included can help you avoid some less-than-obvious pitfalls on the road to optimization.  I've tried to include information here that isn't found in other AS3 optimization white papers, and tried to keep the superflous information to a minimum.

我希望我所包含的技巧可以帮助您避免在优化的道路上出现一些不太明显的陷阱。 我试图在此处包括其他AS3优化白皮书中找不到的信息,并试图将多余的信息保持在最低限度。

Additionally, there are optimization techniques found elsewhere that I question.  For example, in AS3, variable name length doesn't matter (it did in AS2).

另外,我对其他地方的优化技术也有疑问。 例如,在AS3中,变量名称的长度无关紧要(在AS2中确实如此)。

var a:Number = 987234.230948;
var myLongVariableNameUsedToMatterButDoesntAnymore:Number = 987234.230948;

I've also seen developers discourage typing inside a loop, stating that variables that will be referenced within the loop should be typed outside of it.  My own testing does not prove that out.

我还看到开发人员不鼓励在循环中键入内容,指出将在循环中引用的变量应在其外部键入。 我自己的测试无法证明这一点。

var n:Number;
for(var i:int=0;i<10000;i++){
  n = Math.random();
}
for(var i:int=0;i<10000;i++){
  var n:Number = Math.random();
}

Last, a warning: don't try to optimize your code until it's thoroughly debugged.  Make sure everything is working exactly as it should, even under challenging conditions, before worrying about performance.

最后一个警告:在彻底调试代码之前,请不要尝试优化代码。 在担心性能之前,即使在充满挑战的条件下,也请确保所有功能均按预期工作。

翻译自: https://www.experts-exchange.com/articles/2107/20-Tips-to-Optimize-your-ActionScript.html

actionscript

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值