意大利的Marco Lapi和alias Lapo对actionscript的代码优化进行了一系列的测试,通过这些测试,我们可以对如何编写更优化的代码有进一步的了解。测试主要是针对实现同一目的的两种或三种代码的运行时间,当然,时间越少,说明这种方式就越好。下图是测试结果:
(1)for循环和while循环
结论是while循环优于for循环,
(2)遍历数组(for、for...in、while)
结论是for...in结构优于其他两种
(3)向数组写入数据
区别不是很明显,但是while优于for
(4)_global变量和时间轴变量
结论是_global变量优于时间轴变量
(5)单独声明变量和同时声明多个变量
这是单独声明变量:
a = 0;
b = 0;
c = 0;
d = 100;
e = 100;
这是同时声明多个变量:
a = b=c=0;
d = e=100;
结论是同时声明多个变量优于单独声明变量
(6)查找变量名
查找变量名也会花费时间
在循环结构中直接调用函数:
var num = null;
t = getTimer();
for (var i = 0; i<MAX; i++) {
num = Math.floor(MAX)-Math.ceil(MAX);
}
t1.text = "Always lookup: "+(getTimer()-t);
不如在循环结构开始前将函数赋给一个变量:
t = getTimer();
var floor = Math.floor;
var ceil = Math.ceil;
for (var i = 0; i<MAX; i++) {
num = floor(MAX)-ceil(MAX);
}
(7)短变量名优于长变量名,因此尽量让变量名短一点
(8)在循环体中声明变量和在循环开始前声明变量,如下:
在循环体中声明变量:
t = getTimer();
for (var i = 0; i<MAX; i++) {
var test1 = i;
}
t1.text = "Inside:"+(getTimer()-t);
在循环开始前声明变量:
t = getTimer();
var test2;
for (var i = 0; i<MAX; i++) {
test2 = i;
}
结论是差别不大
(9)使用嵌套的if结构
在if结构中假如要判定的并列条件较多,最好将它们拆分成多个if结构,然后嵌套在一起,这样可以避免无谓的判定
MAX = 20000;
a = 1;
b = 2;
c = -3;
d = 4;
//下面是写在一个if中
var i = MAX;
while (--i>-1) {
if (a == 1 && b == 2 && c == 3 && d == 4) {
var k = d*c*b*a;
}
}
//下面是写在拆开的多个嵌套if中
var i = MAX;
while (--i>-1) {
if (a == 1) {
if (b == 2) {
if (c == 3) {
if (d == 4) {
var k = d*c*b*a;
}
}
}
}
}
(10)嵌套循环(for 和 while)
和前面一样,while优于for
(11)tellTarget和点语法
tellTarget是被淘汰的写法,但是!!!事实上tellTarget的性能(从运行时间上说)比点语法好
点语法:
mc._x = 10;
mc._y = 10;
tellTarget语法:
tellTarget (mc) {
_x = 10;
_y = 10;
}
(12)访问局部变量(this和with)
obj = {};
obj.a = 1;
obj.b = 2;
obj.c = 3;
obj.d = 4;
obj.e = 5;
obj.f = 6;
obj.g = 7;
obj.h = 8;
obj.test1 = useThis;
obj.test2 = useWith;
MAX = 10000;
//下面是使用this
function useThis() {
var i = MAX;
while (--i>-1) {
this.a = 1;
this.b = 2;
this.c = 3;
this.d = 4;
this.e = 5;
this.f = 6;
this.g = 7;
this.h = 8;
}
}
//下面是使用with
function useWith() {
var i = MAX;
while (--i>-1) {
with (this) {
a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
f = 6;
g = 7;
h = 8;
}
}
}
结论是this优于with
(13)循环侦听按键
这与第(6)条相似,假如使用变量来代替内置函数和常量,可以节省时间
例如:
if(Key.isDown(Key.LEFT))
可以优化成:
keyDown = Key.isDown;
keyLeft = Key.LEFT;
if(keyDown(keyLeft))
(14)Math.floor()和int()
和tellTarget一样,虽然int是过时的,但是它的速度更快
(15)eval和数组访问
eval:
var mc = eval("_root.myMc"+i);
数组访问:
var mc = _root["myMc"+i];
结论:差别不大
(16)通过影片剪辑循环或是ASBroadcaster
这是循环:
MAX = 500;
SX = 550;
SY = 330;
MovieClip.prototype.onCustomEvent = function() {
this.removeMovieClip();
};
function init() {
var i = MAX;
var rnd = Math.random;
while (--i>-1) {
var m = _root.attachMovie("enemy", "e"+i, i);
m._x = rnd()*SX;
m._y = rnd()*SY;
}
}
init();
function bench() {
var t = getTimer();
var i = MAX;
while (--i>-1) {
_root["e"+i].onCustomEvent();
}
res.text = "time: "+(getTimer()-t);
} 这是ASBroadcaster:
MAX = 500;
evtManager = {};
ASBroadcaster.initialize(evtManager);
SX = 550;
SY = 330;
MovieClip.prototype.onCustomEvent = function() {
this.removeMovieClip();
};
function init() {
var i = MAX;
var rnd = Math.random;
while (--i>-1) {
var m = _root.attachMovie("enemy", "e"+i, i);
m._x = rnd()*SX;
m._y = rnd()*SY;
evtManager.addListener(m);
}
}
init();
function bench() {
var t = getTimer();
evtManager.broadcastMessage("onCustomEvent");
res.text = "time: "+(getTimer()-t);
}
结论是使用ASBroadcaster优于普通循环。 后记:一般的Flash程序对于现在的硬件设备可以说是小菜一碟,不过对于复杂的游戏,注重对代码的优化绝对会对游戏性能有所帮助。而且作为AS程序员,了解一下AS的优化也是应当的。
最近到一些国外的flash网站上看了一下(甚至去过安道尔),觉得他们对AS的研究比中国的要细致得多。在中国至今没有一个有名气的专业AS站点。虽然在中国还没有明显看到AS的大好春光,不过作为一门技术,只要精通,就一定会发挥它的作用。
专业和业余的AS程序员和爱好者,一起努力吧!