打印

讨论——关于Flash 程序的优化

Flash Ation Script的效率不佳,相信写AS的朋友最关心也最头痛的莫过于此了。
所以如何提高AS 的效能值得探讨的。
希望大家能把平时积累的一些经验在此分享一下。

(留个位,明天来补)
hey~同志们还好么?
删除不再用的变量对象
在国外看到一个有意思的讨论,总结了一下,看以下4段代码,清分别执行,看看所用的时间。
复制内容到剪贴板
代码:
var MAX_VALUE = 39999
function loop() {
    var st=getTimer()
    var z;
    for ( i=0; i<MAX_VALUE; i++) {
        z ++;
    }
    trace(getTimer()-st);
}
复制内容到剪贴板
代码:
_global.MAX_VALUE = 39999
function loop() {
    var st=getTimer()
    var z;
    for ( i=0; i<MAX_VALUE; i++) {
        z ++;
    }
    trace(getTimer()-st);
}
复制内容到剪贴板
代码:
function loop() {
                var MAX_VALUE = 39999
    var st=getTimer()
    var z;
    for ( i=0; i<MAX_VALUE; i++) {
        z ++;
    }
    trace(getTimer()-st);
}
复制内容到剪贴板
代码:
function loop() {
                var MAX_VALUE = 39999
    var st=getTimer()
    var z;
    for (var i=0; i<MAX_VALUE; i++) {
        z ++;
    }
    trace(getTimer()-st);
}
hey~同志们还好么?
有意思。以后循环都要加上var了。

TOP

还在为头像烦恼?还在为不能关注好友动态烦忧?快来蓝色理想家园吧!
有意思
复制内容到剪贴板
代码:
_root.MAX_VALUE=39999;
_root.z=0;
function loop() {
    _root.st=getTimer()
    for (_root.i=0; _root.i< _root.MAX_VALUE; _root.i++) {
    _root.z ++;
    }
    trace(getTimer()-_root.st);
}
loop();
-_-b 慢了N倍
★ 卖坏梨的 The Baby Shop ★
http://shop34968454.taobao.com/

TOP

想不到一个VAR竟然快了这么多
如果现实让人更加勇敢,就让我在地狱里追求天堂

TOP

所以,上面的结论是多使用局部变量!

慢的就不要说了,看谁有更快的方法=_=!

hey~同志们还好么?

TOP

看来要尽量使用局部变量。

另外改造一下for循环也能显著提高效率

function loop() {
    var MAX_VALUE = 39999
       var st=getTimer()
       var z;
       for (var i=MAX_VALUE;--i>0;) {
              z ++;
       }
       trace(getTimer()-st);
}

----------
刚才试验了一下javascript,发现javascript执行速度比flash速度快N十倍
[star]team webmaster

TOP

starsjz在上个帖子中说
引用:

另外改造一下for循环也能显著提高效率

function loop() {
    var MAX_VALUE = 39999
       var st=getTimer()
       var z;
       for (var i=MAX_VALUE;--i>0;) {
              z ++;
       }
       trace(getTimer()-st);
}

for (var i=MAX_VALUE;--i>0;) {
z ++;}
为何这样可以提高速度?

TOP

果然...........+比-慢呢
(var i=0;++i<MAX_VALUE;)还是不如(var i=MAX_VALUE;--i>0;)的快
★ 卖坏梨的 The Baby Shop ★
http://shop34968454.taobao.com/

TOP

复制内容到剪贴板
代码:
function loop() {
    var i=MAX_VALUE = 39999
    var st=getTimer()
    var z=0;
    var i;
    while (--i>0) {
        z ++;
    }
    trace(getTimer()-st);
}
function loop2() {
    var i=MAX_VALUE = 39999
    var st=getTimer()
    var z=0;
    var i;
    for (;--i>0;) {
        z ++;
    }
    trace(getTimer()-st);
}
loop();
loop2();
试验了一下,多于半数的情况下while的稍微快那么一点点点点
★ 卖坏梨的 The Baby Shop ★
http://shop34968454.taobao.com/

TOP

非常好!!!
看来这个讨论是很有价值的,要长期讨论下去

除了for,as还有while循环。大家快试试while, 看哪种方式更快。
hey~同志们还好么?

TOP

myhyli在上个帖子中说
引用:

试验了一下,多于半数的情况下while的稍微快那么一点点点点
怎么搞得,你的帖子到我上头去了
hey~同志们还好么?

TOP

主要是判断上的缘故

i<0
i<max
i<obj.length

这3个判断由上到下越来越慢;

---------------------------

另外理论上,(我没在flash试验过),

z++ , ++z , z=z+1 这三种操作,

前两种基本上没有速度的差别,而最后一种最慢.
[star]team webmaster

TOP

抛弃<, 改用 --i-1吧!

faint ,好像花的时间还多些。
hey~同志们还好么?

TOP

循环差不多了吧,程序的优化不仅仅是循环哦
在从一个序列、集合里剔除重复的工作,大家都有什么技巧呢?
★ 卖坏梨的 The Baby Shop ★
http://shop34968454.taobao.com/

TOP

myhyli  你说的 从一个序列、集合里剔除重复的工作 是什么意思啊,我还不太明白。
最好举个例子!
hey~同志们还好么?

TOP

哦,比如要往一个序列里添加内容,但是又不可以是这个序列里已经有的,也就是说保证这个序列里的内容是不重复的,
最常见的是数组,加入很方便,push进去,但是要判断是否重复了,就很麻烦,一般都是用一个for遍历,逐一对比,但是每push一次都要先做个循环判断,就非常之慢
于是改用object,
var xxx={aaa:1,abc:1,ccc:1};
那我在新加入的时候只要判断if(xxx['ddd']!=1)xxx['ddd']=1,不必再遍历
要取得整个序列也很方便,for(var i in xxx)trace(i+'='+xxx[i])

让高手见笑了
★ 卖坏梨的 The Baby Shop ★
http://shop34968454.taobao.com/

TOP

那我在新加入的时候只要判断if(xxx['ddd']!=1)xxx['ddd']=1,不必再遍历


什么意思?看不懂的说
如果现实让人更加勇敢,就让我在地狱里追求天堂

TOP

我想myhyli的意思是以数组的“标签“来存储真正的“值“
以数组的值来决定“标签”的存在与否
把无知当武器?
http://byjog.com/blog重新开张啦

TOP

myhyli在上个帖子中说
引用:
哦,比如要往一个序列里添加内容,但是又不可以是这个序列里已经有的,也就是说保证这个序列里的内容是不重复的,
最常见的是数组,加入很方便,push进去,但是要判断是否重复了,就很麻烦,一般都是用一个for遍历,逐一对比,但是每push一次都要先做个循环判断,就非常之慢
于是改用object,
var xxx={aaa:1,abc:1,ccc:1};
那我在新加入的时候只要判断if(xxx['ddd']!=1)xxx['ddd']=1,不必再遍历
要取得整个序列也很方便,for(var i in xxx)trace(i+'='+xxx[i])

让高手见笑了
这个做法实在事太好了!思想不错,完全可以避免数组历遍。
在flash里面完全适用,如果对于c++这些需要数组预定义的
语言的话,就要改一下了。不过思想方面应该继承。
佩服佩服
Moonfun Studio Devlop Center
bbs.moonfun.com

TOP

能用object的“键-值”查询的地方当然应该尽量使用,flash里的数组实在太慢了。
一个最有说服力的例子就是,如果要遍历一个数组,比如给所有的项赋值,在没有操作顺序的要求下,用for(...in...)要比for(...;...;...)快的多。这就是因为for in在flash执行的时候采用的是先建立“键-值”枚举表,然后再循环的缘故。
英领科技 引领潮流

TOP

myhyli在上个帖子中说
引用:
哦,比如要往一个序列里添加内容,但是又不可以是这个序列里已经有的,也就是说保证这个序列里的内容是不重复的,
最常见的是数组,加入很方便,push进去,但是要判断是否重复了,就很麻烦,一般都是用一个for遍历,逐一对比,但是每push一次都要先做个循环判断,就非常之慢
于是改用object,
var xxx={aaa:1,abc:1,ccc:1};
那我在新加入的时候只要判断if(xxx['ddd']!=1)xxx['ddd']=1,不必再遍历
要取得整个序列也很方便,for(var i in xxx)trace(i+'='+xxx[i])
让高手见笑了
如果插入的是字符串的话,这个方法最好了
不过如果插入的是数字的话,连标标签也用不到
例如插入一个数num
直接if(xxx[num]==1)就行了
利用了flash中数组可以不连续赋值,没被赋值地元素为undefined这一特性
嗬嗬,其实道理和时间复杂度都是一样的
不过不知道这样会不会使空间复杂度增大?
把无知当武器?
http://byjog.com/blog重新开张啦

TOP

1、我们知道,一个数向右位移N位,等价于他乘以2的N次方,从理论上来说,前一种的运算速度会更快,这是因为电脑的CPU对二进制运算处理更快
比如, 3*Math.pow(2,8)这样的表达式,如果用3<<8来运算会来得更快。。。。。
同理,一个数左位移N位也比他除以2的N次方(没有余数)更快。。。

2、如果一个if(exp)语句里的表达试比较复杂,那么实际上你将它分开来判断是一个更好的办法。
比如,
if(exp1 || exp2 || exp3 || exp4){ ....... }
这样的判断语句,而且每个表达式本身也比较复杂的话,如果这样来写:
if(exp1){....}
if(exp2){....}
if(exp3){....}
if(exp4){....}
他的运行会更快,而且超乎你的想象的是——后一种生成的文件比前一种更小!
这个家伙很聪明,什么都没留下......

TOP

楼上的想法很好。不过有些小地方要注意。

1、 如果你没有在flash里做过测试的话,我不敢苟同。 Flash里确实有些东西超乎常理。
2、
if(exp1 || exp2 || exp3 || exp4){ ....... }
不等价于
if(exp1){....}
if(exp2){....}
if(exp3){....}
if(exp4){....}

应该是
if(exp1){....}
else if(exp2){....}
else if(exp3){....}
else if(exp4){....}

运行速度的确加快了。原因很简单
if(exp1 || exp2 || exp3 || exp4){ ....... } 需要对4个表达式求值,而后一种写法大多数情况下不需要。
hey~同志们还好么?

TOP

其实,用
if(exp1){....}
if(exp2){....}
if(exp3){....}
if(exp4){....}
能让文件最小的。。。。
不等价存在的原因是有可能exp1/exp2/exp3/exp4会多个表达式同时为真。。。。
所以,如果多个表达式不存在同时为真的情况,还是用这个好点吧。。。。
哦?蛋蛋。。。。

这个家伙很聪明,什么都没留下......

TOP

不啊,这样的话,即使exp1为真,它仍然会去执行第二行exp2为真的判断,如果为真还会执行里面的代码,也就是说如果有2个以上为真的,会执行多次,而else只执行到首次为真的那一项就不继续执行判断的
非要拆分开写的话,不如在{}里写一个 xxx=1;
然后在最后一个else if后面加一个if(xxx==1){...这里放真正要执行的代码..} 这样就避免在前面的 if 里重复写要执行的代码

.......其实我觉得还是 if(exp1 || exp2 || exp3 || exp4) 这样写条理清晰一点
★ 卖坏梨的 The Baby Shop ★
http://shop34968454.taobao.com/

TOP

嘻,原来FLASH里也可以用这种语法

var x=1.5;

switch(true) {
       case x>1:
              trace('>1');
              break;
       case x<1:
              trace('<1');
              break;
       case x==1:
              trace('=1');
              break;
       }
★ 卖坏梨的 The Baby Shop ★
http://shop34968454.taobao.com/

TOP

晕~这样写都能被你想到,你牛~
英领科技 引领潮流

TOP

不过这样写好像还不如:
if (x>1) {
trace('>1');
} else if (x<1) {
trace('<1');
} else if (x==1) {
trace('=1');
}
英领科技 引领潮流

TOP