谈谈个人对as3优化见解
知识需要去学习、发现,知识需要积累------- kiddy
众所周知,评价一个算法的好与坏,需要考虑两个因素,一个就是时间复杂度,另一个就是空间复杂度,所谓的时间复杂度,简而言之,也就是执行该算法cpu所需要花费的时间;所谓的空间复杂度,也就是执行该算法所需要的内存空间。所以说一个好的算法,执行相同的效果,使用的时间、空间越少越好,对as3算法的优化也是如此,下面谈就谈个人对as3优化的一些见解与看法。
(1)时间负责度
时间负责度的大小主要体现在循环中,当然一些简单的运算也占据了一定的时间。
(I)多个类似循环能够合并在一起的,尽量使用恰当的方式使其合并在一起(ENTER_FRAME , Timer , for ,while …..),比如说:
A.addEventListener(Event.ENTER_FRAME,fun);
B.addEventListener(Event.ENTER_FRAME,fun);
执行合并:
C.addChild(A); C.addChild(B);
C.addEventListener(Event.ENTER_FRAME,fun);
(II)尽量将多个循环嵌套合并成一个循环或更少的循环嵌套,比如说;
for(var i:uint = 0 ; i < n ; i ++)
{
for(var j :uint = 0 ; j < n ; j++)
{
_arr[i*n + j] = i*n + j;
}
}
将嵌套循环合并
for(var i:uint = 0 ; i < n*n ; i++)
{
_arr[i] = i;
}
(III)尽量使用乘法代替除法,使用位运算代替乘法除法,比如说:
用 c = a * 0.5 代替 c = a / 2 ; 用 c = a <<1 代替 c = a * 2 ; 用 c = a >>1 代替 c = a / 2;
(IV) 使用int强制转换代替Math.round ()、Math.ceil()、Math.floor(),例如:
(V)使用 ?: 三目运算符代替简单的if else 语句(注:使用此替代效率未优化,代码简洁)、代替Math.abs(), 例如:
c = a>0 ? a : -a;
代替
c = Math.abs(a);
(V)在数组、向量、对象等遍历时,尽量使用for in/for each in代替for循环,比如说:
for(var i in arr)
{
trace(arr[i]);
}
代替
for(var i:uint = 0 ; i < arr.length ; i++)
{
trace(arr[i]);
}
(VI)尽量使用while代替for (笔者也习惯使用for循环,慢慢纠正吧), 在多层判断中使用switch 代替 if (else if ) else,例如:
var i:uint = 0 ;
while(++i < num)
{
vec.push(i);
}
代替
for(var i:uint = 0 ; i < num; i++)
{
vec.push(i);
}
(VII)关于Timer 和EnterFrame的选择上,Timer会比EnterFrame更好点。不过具体情况还要具体看待。
(VIII)String对象使用 += 运算符效率高于concat函数 ,比如说:使用str += str2效率高于 str.concat(str2) ;
关于时间复杂度目前只想到这么多,想到了再添加进去
(2)空间复杂度
空间的复杂度,主要体现在内存的开辟,说到空间复杂度,不得不说说SWF(AVM2)垃圾的回收以及内存泄露,AVM2垃圾自动回收并不是我们想象中的那么良好,具体的垃圾回收请阅览:http://rss.9ria.com/?p=4143 (写的眼睛有点痛,脑袋也快要麻木了,今天到此为止,明天继续写关于空间复杂度)(新的一天、新的生活已经开始了,go on)
(I)使用内存占用小的类型对象代替占用内存大的类型对象。常用的有:
A.Shap < Sprite < MovieClip
B.int、uint < Number
C.Vector < Array (注:在所有元素均具有相同数据类型的数组时可用);
(II)能使用局部变量时,尽量使用局部变量,而不是全局变量;此外还要少使用静态局部变量和静态局部方法(当然单例模式例外),例如:
public funciton exchange(var num1:Number , var num2:Number):void
{
var t:Number;
t = num1 ;
num1 = num 2 ;
...
}
代替
private var t:Number;
public funciton exchange(var num1:Number , var num2:Number):void
{
t = num1 ;
num1 = num 2 ;
num2 = t;
...
}
(III)在for循环外部定变量,而不是在for循环内部定义变量,避免一直new 对象出来。比如:
var obj:Object
for(var i :uint = 0 ; i < n ; i++)
{
obj = new Object();
}
代替
for(var i :uint = 0 ; i < n ; i++)
{
Var obj:Object = new Object();
}
(IV)在for循环遍历数组或其他对象时,循环条件,最好首先在外部赋值,尤其是在循环次数较多时。例如:
var length = arr.length;
for(var i:uint = 0 ; i < length ; i++)
{ ......... }
代替
for(var i:uint = 0 ; i < arr.length ; i++)
{ ......... }
(V)关于矢量图和位图,能够使用位图时尽量使用位图,避免使用矢量图时进行过多的计算,部分显示对象可以使用 disObj.casheAsBitmap = true 转换成位图。使用图形最好使用png格式,但是最好不带透明度的,透明度也需要计算。
(VI)当一个对象使用完毕时,要及时将其进行回收,移除其监听事件,removeChild,设置为null 而不是等待系统自动回收,或者更为简单的visiable = false;例如:
button.removeEventListener(MouseEvent.CLICK , onMouseClick);
this.removeChild(button);
Button = null;
而不是
Button.visiable = false;
(VII)对象池的使用,笔者认为对象池,并不能节省很多的空间,但是它却有非常使用的地方,比如说在remove时或者不需要使用的时候,可以自己自动清除该对象或者其属性等,等到需要用的时候再拿出来,不需要的时候进行清除。
(VIII)监听事件进行组合,许多同样的监听事件可以合并在一起的,尽量合并在一起(有点类似与时间优化案例1),如:
redButton.addEventListener(MouseEvent.CLICK, onMouseClick);
buleButton.addEventListener(MouseEvent.CLICK, onMouseClick);
greenButton.addEventListener(MouseEvent.CLICK, onMouseClick);
进行合并:
button.addChild(redButton);
button.addChild(buleButton);
button.addChild(greenButton);
button.addEventListener(MouseEvent.CLICK, onMouseClick);
关于空间复杂度目前只想到这么多,想到了再添加进去。
文章差不多也就结尾了,对于as3的学习还不够深入,笔者会更加努力和用功,如果存在错误,请直接指出,如果您有更好的优化想法,欢迎和大家进行交流、探讨以及分享。。。。。。
一分收获,十分付出——未经笔者允许请勿随便转载或传递,请珍惜笔者的汗水。………………………………………………………………………2013.9.9