AS代码优化技巧

第一章  AS3的一些优化计算方法
来源:John Grden Blog

1.用乘法来代替除法(当除数可转化为有限数的时候)。比如var n:Number = value * 0.5;要比var n:Number = value / 2;快。但差别并不是很大。只有在需要大量计算情况下,比如3D引擎中差别才比较明显。

2.用位运算代替除2或乘2。比如10>>1要比10*2快,而10<<1要比10*2 快。从测试来看位运算几乎比乘除快一倍,但是一般情况下,我们不能选择位运算,比如我们就不能用13>>1来代替13/2,尽管前者比后者运算速度更快,但2者的运算结果却不一样。所以还是要看具体情况。

3.用unit()或int()代替取整运算Math.floor()和Math.ceil()。比如var test:uint = uint(1.5);要比var test:Number = Math.floor(1.5);快;而var test:uint = uint(1.5)+1;要比var test:Number = Math.ceil(1.5);也快。如果是Math.floor(),还可以用位运算(>>0)来代替。比如var test:uint =1.5>>0,比unit()或int()更快。

4.用乘-1来代替Math.abs()方法。比如var nn:Number = -23;var test:Number= nn < 0 ? nn * -1 : nn;要比var nn:Number = -23;var test:Number = Math.abs(nn);快。

当然还有更多的优化计算的方法。一般来说,低级运算要比高级运算速度;内部方法比调用其他方法速度快。另外要注意的是,这些方法有的时候可能并一定适用。

第二章  Actionscript 优化指南
来源 gotoAndStop.it

原著 Marco Lapi,alias Lapo, aw译

在这篇文章中,我们将讨论多种优化 Actionscript 代码的方法.
此外我们也针对一些典型的游戏代码进行了系列测试,来最大限度的发掘、提高Flash播放器的性能。

何时进行优化

对现有程序进行优化的过程,有时十分的冗长与困难,这与原始代码的非优化程度有关,所以在投入大量时间进行代码优化之前,最重要的是要估计出要在什么地方对代码做出修改或替换。

一个游戏代码的最重要的部分就是主循环体,通常情况下该循环体要在flash的每一帧上执行,并控制游戏中的角色属性和重要的数据参数。而对于主循环体以外的部分,也可能是次要循环部分,同样要注意是给其否分配了过多的资源,而没有分配给那些更需要资源的核心部分。
通过积累在各处节约出来的时间(可能每处仅仅是几个毫秒),您会明显发现自己的swf运行得更加稳定,并且游戏感也大大加强。

简洁与高效的代码

书写出十分简洁、可以再次调用的代码(有时可能是面向对象的)是一项精细的工作,但这需要多年的编程经验。对于OOP(object oriented programming,面向对象的程序设计),有些场合根本利用不到它的优势,这使得它显得十分奢侈。在有限的资源条件下(可能是flash播放器的原因),通过更先进的方法,像刚刚提到的OOP,就可能反而导致令人不满意的结果。

我们并不是说OOP对游戏编程不好,只是在某些场合它显得过于奢侈和多余。毕竟有时候“传统的方法”却能得到更好的结果。

大体而言,用OOP是比较好的,因为它让代码维护更加简单。但在后文中,你会看到有时为了充分发挥flashplayer性能,而不采用OOP技术。例如:处理快速滚动或者计算十分复杂的数学问题。

基本的优化

一提及代码优化,我们马上会联想到执行速度的改进,而很少去考虑系统资源的分配。这是因为当今,即使是将被淘汰的计算机,都有足够的内存来运行我们大部分的flash游戏(128M的内存足以满足大多数情况的需要,况且,512M的内存是当今新电脑的基本配置)

变量

在各种重要的代码优化手段中,有这么一条:在定义局部变量的时候,一定要用关键字var来定义,因为在Flash播放器中,局部变量的运行速度更快,而且在他们的作用域外是不耗占系统资源的。

aw附:var变量仅仅在花括号对中才有“生命”,个人认为没有系统学过编程的人容易出错的一个地方:

awMC.onLoad = function(){
  var aw = 1;
}
awMC.onEnterFrame = function(){
//不存在aw这个变量
}
一段非优化代码:

function doSomething()
{
mx = 100
my = 100
ar = new Array()

for (y=0; y < my; y++)
{
  for (x=0; x < mx; x++)
  {
   i = (y * mx) + x
   arr[i] = i   
  }
}

return arr
}

这段代码中,并未声明函数体内的那些变量(那些仅仅在函数内使用的变量)为局部变量,这使得这些变量被播放器调用的速度更慢,并且在函数执行完毕的时候仍然耗占系统资源。

下面列出的是经过改进的同样功能的代码:

function doSomething()
{
var mx = 100
var my = 100
var ar = new Array()

for (var y=0; y < my; y++)
{
  for (var x=0; x < mx; x++)
  {
   var i = (y * mx) + x
   arr[i] = i   
  }
}
return arr
}
这样一来所有的变量均被定义为了局部变量,他们能够更快地被播放器调用。这一点在函数大量(10,000次)循环运行时显得尤为重要!当一个函数调用结束的时候,相应的局部变量都会被销毁,并且释放出他们占有的系统资源。

onEnterFrame 事件

onEnterFrame事件对于游戏开发者而言是非常有用的,它使得我们能够快速、反复地按照预设帧频(fps)运行一段程序。回想在Flash5的时代,这(onEnterFrame实时监控)是一种非常流行的技术,用这样的事件来控制机器游戏对手的逻辑,又或者我们可以在每一个子弹上设置这样的事件来监测子弹的碰撞。

实际上,我们并不推荐给过多的MoveClip添加这样的事件,因为这样做会导致“无头绪码(spaghetti code)”的出现,并且容易导致程序效率明显降低。

大多数情况下,用单独一个onEnterFrame事件就可以解决问题了:用这一个主循环来执行你所需要的操作。

另一个简单的办法是设置一个合适的帧频:要知道帧频越高,CPU资源就越紧张。

在帧频为25-35(fps)之间时,onEnterFrame足以很好地执行较复杂代码,哪怕你的计算机配置较低。因此,在没有特殊要求的场合,我们不推荐使用高于60(fps)的帧频。

矢量图与位图

在处理图形前,我们一定要做出正确的选择。Flash能对矢量图和位图进行完美的兼容,然而矢量图和位图在播放器中的表现实质却完全不同。

在用到矢量图的时候,我们要尽可能简化它们的形状,去除多余的端点。这样做将大大降低播放器用于呈现矢量图所要进行的计算量。另一个重要方面在于线条的运用,尽量减少和避免冗陈的线条结构,因为它们会直接影响到flash的播放效率。

当某个实例透明度小于100时,也会对播放速率造成影响,所以如果你发现自己的Flash播放速率过慢,就去挑出这些透明的实例来吧!

那么,如果真的需要呈现比较复杂的场景时,你就最好考虑使用位图实现。虽然Flash在对位图的渲染效率上并不是最优越的(比如和Flash的“兄长” Director比起来),但丰富的视觉内容呈现只能靠位图(与位图同复杂度的矢量图形渲染速率非常低)了,这也是很多基于区块的游戏中广泛采用像素图作为背景的原因。顺便要提到的是,Flash虽然对GIF,JPG和PNG都有所支持,但是渲染速度上PNG还是占有绝对优势,所以我们建议flash中的位图都尽可能采用PNG格式。

影片剪辑(MovieClip)的可视性[下面将MovieClip简称为mc]

您可能会经常碰到这样一种情况:有大量不可见/屏幕外的mc等待出场(比如游戏中屏幕外的地图、人物等等)。
要知道,播放器仍然要消耗一定的资源来处理这些不可见/屏幕外的mc,哪怕他们是单帧,非播放的状态。

最好的解决办法之一是给这些mc一个空白帧,当他们不出现在屏幕上时,你能用gotoAndStop()语句跳转到这一帧,从而减少播放器对资源的需求。

请务必记住,这种情况下,简单的设置可见度属性为不可见( _visible = false )是无效的,播放器将继续按照这些mc所停留或播放的帧的复杂度来分配资源。

数组
数组在各种需要记录数据的应用程序和游戏中都被广泛的使用。

一个典型的例子就是基于区块的Flash游戏,在这样一类的游戏中,地图有时被存放成形如arr[y][x]的二维数组。虽然这是一种很常见的方法,但是如果用一维数组的话,却能提高程序的运行效率。另一个重要的方法来提高数组效率是在数组遍历的时候使用for in 循环来代替传统的 for 或者while循环语法。
例如:

一段代码如下
for (var i in arr)
{
if (arr[i] > 50)
{
  // 进行某些操作
}
}

它的执行速度明显高于这一段代码:
for (var i=0; i<10000; i++)
{
if (arr[i] > 50)
{
  // 进行某些操作
}
}
前者的效率比后者提高了30%,这个数字在你的游戏要逐帧执行这一段代码的时候显得更加宝贵!

高级优化:
1) for循环 和 while循环
用while循环将会得到比for循环更好的效率。然而,从数组中读取数据,用for in循环式最好的选择!

所以我们不推荐使用:
for (var i=0; i<1000; i++)
{
//进行某些操作
}而推荐使用

var i=-1
while (++i < 1000)
{
//进行某些操作
}

2) 从数组中读取数据
我们通过测试发现,for in循环的效率大大高于其他的循环方式。参看:
arr = []
MAX = 5000

//数组赋值
for (i=0; i < MAX; i++)
{
arr[i] = i
}
var item = null

// For Loop
for (var i=0; i < MAX; i++)
{
item = arr[i]
}

//For循环
for (var i in arr)
{
item = arr[i]
}

// While循环
i = -1
while(++i < MAX)
{
item = arr[i]
}

3) 向数组中写入数据(while , for)
可以看到while循环稍占优势。

4) _global(全局)变量同Timeline(时间轴)变量
我们猜测采用全局变量能提高变量调用速度,然而效果并不像预计的那样明显。

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) 短变量名和长变量名
变量名越短,效率越高。考虑到长变量名也有它的好处(比如,便于维护等),因此建议在关键部位(比如大量循环出现的时候)使用短变量名,最好就1-2个字符。

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结构
当用到复杂的条件表达式时。把他们打散成为嵌套的独立判断结构是最佳方案。下面的代码我们进行了测试,发现这种效果改进明显!
MAX = 20000
a = 1
b = 2
c = -3
d = 4

var i=MAX
while(--i > -1)
{
if (a == 1 && b == 2 && c == 3 && d == 4)
{
  var k = d * c * b * a
}
}

//下面的判断更加节省时间
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) 寻找局部变量(this方法同with方法比较)
局部变量的定位方法很多。我们发现用with比用this更加有优势!
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
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
}
}
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
  }
}
}

11) 循环监听键盘事件
同刚才所提到的寻址一样,我们实现给一个指向会得到更好的效率,比如:
keyDown = Key.isDown
keyLeft = Key.LEFT

//我们再用 if (keyDown(keyLeft))
附:我们测试了按键代码和键值常量的效率发现并无太大差别。

12) Math.floor()方法与int()
这个问题曾在Flashkit的论坛被提出讨论过。测试表明,旧的int方法反而效率更高。我们的测试结果也反映了这一点。

13)eval表达式与中括号语法
我们并没有发现明显的差别,并不像刚才所述那样,旧的eval表达式比起中括号方法并没有太大的优势
var mc = eval("_root.myMc" + i)
var mc = _root["myMc" + i]
//两者效率差不多16) 涉及MC的循环:ASBroadcaster 同欢同循环的差别

结论
我们从这些测试结果中发现,对于不同的需求,采用不同的代码,我们可以大大提高脚本的执行效率。虽然我们在这里罗列了许多的优化代码的方法,需要大家自己测试、实验的还有很多(考虑到每个人的需求不同).如果你想更加深入地讨论这类问题。可以来我们的论坛。

aw附:
终于翻译完了,自己也学到很多好东西,大家又什么问题可以去gotoAndPlay的官方,也可以来我的Blog提出!

第三章  黑羽AS心得:浅释ActionScript的代码优化
来源:Kingda blog

本文既为浅谈代码优化,那么就不深入到OOP设计层面。仅涉及Flash8帮助里面提到的一些代码编写优化原则,并加以解释。
准则来源于Flash8 帮助,我做了一些解释:

1.避免从一个循环中多次调用一个函数。
在循环中包含小函数的内容,可使效果更佳。小函数生命期短,利于资源释放。尤其是在大的循环中时。

2.尽可能使用本机函数。
本机函数要比用户定义的函数运行速度更快。本机函数即Flash中内有的一些函数(intrinsic),比如hitTest(),你没必要自己写一个类似的。

3.不要过多使用 Object 类型。
数据类型注释应力求精确,这样可以提高性能。只有在没有适当的备选数据类型时,才使用 Object 类型。同时也便于代码管理,时刻知道对象的类型和作用。
同时也有利于编译器编译时优化。

4.避免使用 eval() 函数或数据访问运算符。
通常,较为可取且更有效的做法是只设置一次局部引用。不得已时才用eval,比如转换_droptarget为MovieClip时。

5.在开始循环前将 Array.length 赋予变量,尤其是大的循环。
在开始循环前将 Array.length 赋予变量(比如var iLength:Number),将其作为条件使用,而不是使用 myArr.length 本身。
原因,在循环中,iLength是Number变量,会被放入寄存器使用,效率远比访问Array再得到length高。例如,应使用

var fontArr:Array = TextField.getFontList();
var arrayLen:Number = fontArr.length;
for (var i:Number = 0; i < arrayLen; i++) {
    trace(fontArr[i]);
}

来代替:
var fontArr:Array = TextField.getFontList();
for (var i:Number = 0; i < fontArr.length; i++) {
    trace(fontArr[i]);
}

6.注重优化循环及所有重复动作。
Flash Player 花费许多时间来处理循环(如使用 setInterval() 函数的循环)。

7.在局部变量够用时,不要使用全局变量。类静态变量也要少用。
全局变量是开发者的恶梦。实在需要全局变量的话,我建议使用singleton设计模式来进行管理。

8.声明变量时,添加 var 关键字。
这是为了编译时让编译器知道你的变量类型,优化编译。

黑羽补充一点:对关键字的使用要谨慎。
不赞成使用关键字作为自己的method和属性名,除非你确认后续开发不会用到相同的事件名和属性名。
但你怎么知道flash使用了多少隐藏关键字?太多了!比如说 className, invalidate, refresh, mouseOver等等不常用的关键词。好的方法是使用SEPY编辑器来写代码,那里面加亮了所有公布的和没有公布的关键词。
而且因为很有可能和start,load,等这些常用的事件名重复,带来代码不必要的修改和麻烦。

9.对涉及到调用绘图资源的函数时,尽量先多判断再调用。
所有渐变,位置变化,创建删除MC,组件等函数都涉及到绘图资源的调用。在很多情况下,尽量先用逻辑判断变量或者对象的属性,必要时再调用这些函数。这样可以节省较多的计算资源。

时间: 2024-10-30 14:29:11

AS代码优化技巧的相关文章

PHP代码优化技巧大盘点

原文:PHP代码优化技巧大盘点 PHP优化的目的是花最少的代价换来最快的运行速度与最容易维护的代码.本文给大家提供全面的优化技巧. 1.echo比print快. 2.使用echo的多重参数代替字符串连接. 3.在执行for循环之前确定最大循环数,不要每循环一次都计算最大值,最好运用foreach代替. 4.对global变量,应该用完就unset()掉. 5.用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会. 6.函数代替正则表达式完成相

开发出高性能的网站第一部分:20个客户端代码优化技巧

 这个分为三部分的文章概述了一个直观的.省时省力的方法来提升访问网站的速度,这是基于网站性能有关的两个简单法则: 尽可能的减少数据的传输量 尽可能的减少数据的传输频率 若使用得当,此两条法则会: 提高网页的加载速度 降低服务器使用的资源 提高网络带宽利用率 使用这些技巧来开发网站,不仅能够提高用户对一个网站或者是基于web的一个应用的满意度,更可以节约网站数据传输的成本.这篇文章所讲述的技术细节可帮助我们写出很好很实用的代码,从更广泛的角度来讲,这也将会给网站打造出良好的可用性基础. 20个客户

Python 性能诊断及代码优化技巧

    程序代码的优化通常包含:减小代码的体积,提高代码的运行效率.这样可以让程序运行得更快.下面我们来具体谈谈 Python 代码优化常见技巧. 改进算法,选择合适的数据结构 一个良好的算法能够对性能起到关键作用,因此性能改进的首要点是对算法的改进.在算法的时间复杂度排序上依次是: O(1) -> O(lg n) -> O(n lg n) -> O(n^2) -> O(n^3) -> O(n^k) -> O(k^n) -> O(n!) 因此如果能够在时间复杂度上

wordpress网站SEO代码优化技巧

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 WordPress因其功能强大,插件众多,易于扩充功能.安装使用都非常方便,且免费的模版插件深受众多站长们的喜爱,制作成本低,网站易用性强,使大部分初入站长行业的站长们选择WordPress用来作站.用WordPress来做博客.单页面.淘宝客网站都是不错的选择. 在我们使用WordPress做网站的时候,WordPress其实也有不少缺点,

JS代码优化技巧之通俗版(减少js体积)_javascript技巧

细读完这篇文章,够你优化大半天的了,关于JS优化方法大都脱离不了这三种方法. (网页总大小为155.k,而JS就占了100.3K) 是时候优化下JS了 关于JS优化的文章已经很多了,大多技术性很强,像什么变量.字符串.类型,就不做介绍了,也不需要介绍,我也不懂,你知道了也没用.大多数站长都是"拿来主义",我只需要告诉JS怎么放,删那里就可以了. 现在的网站都加的有统计代码.分享工具.评论列表.相关文章插件等工具,而要实现强大的功能,必须使用JS文件,正是这些JS插件,再增强了网站功能的

JavaScript 开发规范要求(图文并茂)_javascript技巧

本人在开发工作中就曾与不按规范来开发的同事合作过,与他合作就不能用"愉快"来形容了.现在本人撰写此文的目的除了与大家分享一点点经验外,更多的是希望对未来的合作伙伴能够起到一定的借鉴作用.当然,如果我说的有不科学的地方还希望各路前辈多多指教.下面分条目列出各种规范要求,这些要求都是针对同事编码毛病提出来的,好些行业约定的其它规范可能不会再提及. 1.保证代码压缩后不出错 对于大型的JavaScript项目,一般会在产品发布时对项目包含的所有JavaScript文件进行压缩处理,比如可以利

解析Android开发优化之:从代码角度进行优化的技巧_Android

通常我们写程序,都是在项目计划的压力下完成的,此时完成的代码可以完成具体业务逻辑,但是性能不一定是最优化的.一般来说,优秀的程序员在写完代码之后都会不断的对代码进行重构.重构的好处有很多,其中一点,就是对代码进行优化,提高软件的性能.下面我们就从几个方面来了解Android开发过程中的代码优化. 1)静态变量引起内存泄露 在代码优化的过程中,我们需要对代码中的静态变量特别留意.静态变量是类相关的变量,它的生命周期是从这个类被声明,到这个类彻底被垃圾回收器回收才会被销毁.所以,一般情况下,静态变量

JavaScript开发规范 降低代码与XHTML耦合性

作为一名开发人员(WEB前端JavaScript开发),不规范的开发不仅使日后代码维护变的困难,同时也不利于团队的合作,通常还会带来代码安 全以及执行效率上的问题.本人在开发工作中就曾与不按规范来开发的同事合作过,与他合作就不能用"愉快"来形容了.现在本人撰写此文的目的除了与大家分享 一点点经验外,更多的是希望对未来的合作伙伴能够起到一定的借鉴作用.当然,如果我说的有不科学的地方还希望各路前辈多多指教.下面分条目列出各种规范要 求,这些要求都是针对同事编码毛病提出来的,好些行业约定的其

JavaScript开发规范要求

原文http://www.cnblogs.com/webflash/archive/2010/06/11/1756255.html   作为一名开发人员(WEB前端JavaScript开发),不规范的开发不仅使日后代码 维护变的困难,同时也不利于团队的合作,通常还会带来代码安全以及执行效率上的问题.本人在开发工作中就曾与不按规范来开发的同事合作过,与他合作就不能 用"愉快"来形容了.现在本人撰写此文的目的除了与大家分享一点点经验外,更多的是希望对未来的合作伙伴能够起到一定的借鉴作用.当