[转]优化Flash性能

原文:http://www.adobe.com/devnet/flash/articles/optimizing-flash-performance.html

翻译:http://bbs.9ria.com/thread-156860-1-1.html

 

 

在这篇文章中,你会学到优化Flash Professional应用性能的策略。优化过程包括编辑你的FLA工程文档确保发布的应用程序帧频可以满足动画的播放流畅。

 

如果你曾运行过一个Flash工程,见过播放总是停顿的动画,当然这种情况你非常不想看到。如果你想来做测验重现这种停顿的动画,可以创建一个有简单动画的工程,然后设置帧频为小于10的任意数字(例如5)。然后发布,可以看到这个动画有多么停顿了。

 

有两个主要因素可以决定Flash的性能:CPUGPU[解释:图形处理器(Graphics Processing Unit) ]的使用和内存的使用。这些因素不是互相独立的。一些优化方法也许在这个方面可以提升性能,但是会对另一个方面有副作用。在下面的单元里,我会解释他们的工作原理,提供一些让你可以明确的做决定的原因,比如,为了降低CPUGPU的加载而增加内存的使用。

 

如果你是为移动设备开发Flash游戏的,很可能你需要一些下面将要讨论的技术手段来达到可接受的帧频。如果你是开发桌面应用的(非游戏),很可能用很小的帧频就可以达到可接受的效果,或者不熟悉这篇文章里描述的技术也可以。

 

判断和衡量游戏性能

 

在理想的世界里,Flash的测试环境允许你模仿目标平台,然后根据目标平台的情况判断你的应用运行情况。不幸的是,除非你的开发平台和目标平台相似,否则现在还不能评估出在测试环境中你的项目的运行情况。

 

除非,你在开发环境中衡量你的应用性能,然后定期让它在目标平台中运行一下,确认它在目标平台也运行良好。

 

如何你在目标平台测试项目并发现问题,你可以用MT类来调试你的应用来解决问题。(在提供的例子文件文件夹内,打开位于这个目录的AS类:MT/com/kglad/MT.as。)

 

内存追踪,内存使用,和性能测试

MT代码改编自Damian Connolly,可以访问他的网站。这个MT类会打印出帧频、内存消耗,列出内存中存在的对象。为了更好使用MT类,遵循以下步骤:

 

1.导入MT类:

  import com.kglad.MT;

 

2.在文档类里初始化它,或在项目的主时间轴上这样写:

  MT.init(this,reportFrequency);

  上面这行代码,“this”表示引用影片的主时间轴,“reportFrequency”表示一个有符号整数(这个数字是自己填的)。主时间轴的引用是用来计算和实现帧频的,reportFrequency是频率(以秒计算),它会跟踪一个Flash应用的帧频输出报告和内存数量的消耗。如果你不想定时输出帧频和内存报告数据,传0(或比0更小的数字)。即使你选择不输出帧频,你仍然运行了这个类的内存跟踪。

 

3.为了跟踪应用里你创建的对象,加上这句话:

MT.track(whatever_object,any_detail);

上面这行代码的第一个参数是你想跟踪的对象(看看它是否从内存中移除了),第二个参数是可选的字符串,它包含任何你想测试的东西。(有些开发人员会用这个参数得到特定对象是什么,在哪和或者存在的时间等细节。)

 

4.为了创建报告,显示你跟踪的对象是否还在内存里,加上这句话:

MT.report();

你没必要了解MT的代码,只管用就行了。但是,了解一些Dictionary类是如何存储所有传给MT.track()的弱引用也是好的。这个类里包括如何使用它的注释。

 

在这篇文章的开头提供了许多使用MT类的示例文件测试。为了更多的学习MT类,查看这些测试例子看看MT类是怎么用的。

就像物理里的观察者效应,我们观察帧频和(或者)内存,和(或者)跟踪内存,改变应用的帧频和内存使用情况。但是,如果观察输出结果比较少很可能观察的效果也会降低。此外,没有绝对的观察数字。每过一段时间调试和优化,改变帧频和/内存使用的情况才是最重要的。MT类很好的做到了承担追踪这些变化的责任。

 

为了降低因为频繁调用trace方法,而出现虚假的低帧频情况,MT类不允许每秒输出结果。(trace方法本身会降低帧频。)要十分注意这点,如果可以的话,你可以用textfield代替trace方法,来尽可能的消除调用trace方法给帧频带来的混淆影响。

 

在范例文件测试工程里,MT类是唯一工具来检查内存使用和精确的内存问题。你也可以直接检查CPUGPU的使用情况(查看执行应用程序时帧频的实际使用情况【就是看资源管理器】)。

 

 

实现优化算法

 

 

 

在这个单元,我会开始做一些内存管理的指导,下面单元标题的顺序是按照首字母排序的。然后为了这个目的,我会提供有关CPU/GPU管理信息的子标题来探讨。

 

 

 

也许我们会觉得提供两个单元的技术是合理的。但是,如果你通读完这篇文章,知道了用内存管理影响CPU/GPU的方法,那么列出的内存管理的建议,可以和CPU/GPU单元里列出的方法一起使用,这样效果会更好。

 

 

 

在为你提供特定的最佳实现方法之前,我认为技术问题同样重要,知道的多了你就学的轻松,反之就会很累。我同样会列第二个清单,它会按技术获益的优先级次序从高到低排列。

 

记住这些清单是主观的。它的顺序是依据个人开发经验和能力来定的,还有测试情形和测试环境。


应用的优化技术从易到难排列

 

1.不要使用滤镜

 

2.尽可能使用倒序for循环,避免使用do循环和while循环

 

3.明确的停止使用Timer,以便垃圾回收

 

4.使用弱引用时间侦听器,当不用的时候移除

 

5.尽可能在任何时候严格定义变量类型

 

6.当不需要鼠标交互的时候明确的禁用鼠标交互

 

7.尽可能在任何时候使用回调函数来取代dispatchEvent(继承的)类

 

8.不需要声音时停止Sound类,以便垃圾回收Sound(继承的)类和SoundChannel(继承的)类

 

9.尽量让每一个所需的元素使用最基本的DisplayObject

 

10.Air应用(移动设备)总是使用cacheAsBitmap 和cacheAsBitmapMatrix (前一个是位图缓存,后一个是位图矩阵缓存?我没用过)

 

11.尽可能在任何时候重新使用Object

 

12.Event.ENTER_FRAME循环:使用不同的侦听器和不同的侦听函数应用在尽可能少的DisplayObjects 上

 

13.用PoolObject(对象池)取代创建和垃圾回收Object

 

14.使用局部位图传输(块传输)

 

15.使用阶段的块传输

 

16.使用Stage3D

 

 

 

优化技术后好处由大到小排列

 

1.使用阶段的块传输(如果有足够的系统内存)

 

2.使用Stage3D

 

3.使用局部位图传输(块传输)

 

4.在移动设备上使用cacheAsBitmap 和cacheAsBitmapMatrix

 

5.当鼠标交互不需要的时候明确的禁用鼠标交互

 

6.不要使用滤镜

 

7.需要的时候使用最基本的DisplayObject

 

8.尽量在任何时候重新利用对象

 

9.Event.ENTER_FRAME循环:使用不同的侦听器和侦听函数,他们最好应用在尽可能少的DisplayObjects 上

 

10.尽可能使用倒序for循环,避免使用do循环和while循环

 

11.用PoolObject(对象池)取代创建和垃圾回收Object

 

12.尽可能在任何时候严格定义变量类型

 

13.使用弱引用时间侦听器,当不用的时候移除

 

14.尽可能在任何时候使用回调函数来取代dispatchEvent(继承的)类

 

15.明确的停止使用Timer,以便垃圾回收

 

16.不需要声音时停止Sound类,以便垃圾回收Sound(继承的)类和SoundChannel(继承的)类

 

记住这些优先级排序,然后前进到下个单元,学习如何更新你的Flash工程来更有效率的管理内存。

 

 

管理内存

 

下面列的建议不够详尽,但它包括了那些可以大幅度提升Flash性能的策略内容。

 

 

 

使用回调函数 VS dispatEvent

 

 

 

当派发事件的时候会增加内存的使用,因为每个事件必须被创建并且分配内存给它。这种行为是这样解释的:事件也是对象,因此也需要内存。

 

我试着发送少量事件,发现每个消耗40128字节。我也发现使用回调函数会使用更少的内存,比使用事件效率更高。(查看在实例文档里的测试文件callback_v_dispatchEvent。)


应用滤镜

 

 

 

当你大量应用滤镜时也很消耗内存。根据Adobe帮助文档使用一个滤镜会消耗双倍内存。在真实Flash Professional CS6的测试环境中,我曾发现使用滤镜的确会增加内存消耗,但是这种消耗不接近双倍内存。(回顾测试范例,在filters文件夹下)

 

 

 

为每个元素使用正确类型的现实对象


Shape,Sprite,MovieClip对象每个都使用不同的内存数量。一个Shape对象需要236字节,Sprite需要412字节,MovieClip需要448字节。

 

 

 

如果你在一个工程里使用上千的显示对象,如果不需要交互的话,你也许需要大量Shape类来拯救你的内存。或者,当不需要时间轴时使用Sprite类。

 

 

 

对象池

 

 

 

当你打开你的应用时,要创建各种你会一直使用的对象引用,对象池可以将这些引用保存在数组里。任何时候一个对象需要时,就可以从这个数组里取出使用。


无论何时当一个对象不再需要时,把它再重新放回数组里。

 

有种常规做法是用Vector来代替Array来存储相同类型的对象。使用Vector也许可以比使用Array快两倍,但是!除非你要做成百上千次的操作,否则你不会注意到两者的差别,因为小于上千次的操作它们一样快。(可以看看array_v_vector 文件夹下的范例文件。)


使用对象池可以获得性能上的好处,同时更主要的收益是让管理内存变得简单。如果你在内存利用方面有无限制增长的问题,用对象池可以很好的解决,它是提高性能、降低内存使用的通用技术。


我看到当测试一个每帧包含许多要垃圾回收和再利用的SWF文件里,使用对象池后帧频快了10%,而内存使用则减少了10%。(可以查看pooling_v_gc 文件夹里的范例。)


重用对象

 

 

 

当你要在一个循环里创建许多对象时,最好在循环外先创建一个对象,然后再循环里重复利用它。当然这个方法也不是对所有工程都有效的,但在很多情况下这个技术还是有用的。


在描述位图传输的单元包括一个重用大量对象的例子。你可以在测试文档里看这是怎么实现的。


处理声音

 

 

 

有关声音的问题在内存使用方面是非常小儿科的。当播放一段声音时,它不可能被垃圾回收的(可以使用Flash Professional CS6来测试文件)。当声音播放完或一个SoundChannel实例执行停止声音时,Sound类就准备垃圾回收了。(想学更多的话可以看看名为sound_test 文件夹下的范例。)


使用Timer

 

 

 

使用Timer时要格外小心。如果没有停止Timer(有两种情况:1.currentCount 属性小于它的循环次数;2.没有调用stop()方法),Timer就不会被垃圾回收,即使你已经移除了侦听器,然后将所有引用设为null。一旦你移除了侦听器,Timer的侦听函数就不被再次调用,但是Timer却仍然消耗内存。

 

 

 

Timer类仅仅使用72字节的内存,所以很可能在一个基于桌面/浏览器的Flash游戏里成为一个很不起眼的问题。但是,当你在移动设备里反复的打开、播放、关闭游戏,然后不断重复启动游戏,你也许就看到这个难以忽略的问题了。

 

 

 

看看这个代码,打开命名为gc_timer_test文件夹下的文件。


弱引用侦听器 VS 强引用侦听器

 

 

 

另一种无法预料的测试结果是,你使用MT类没有办法看出使用弱引用侦听器和强引用侦听器的差别。在Flash Professional CS6环境下我的测试里它们都被当做弱引用侦听器来对待。(查看strong_v_weak_listeners 文件夹下的范例。)

 

管理CPU/GPU使用情况

 

当前,我唯一知道如何直接查看的工具就是使用操作系统自带的。Windows里有一个任务管理(性能选项卡)和Mac OS提供的活动监视器。这两个工具都可以让你看CPU的使用情况,但是一般来说,它们对测试Flash性能不是特别有用。

 

结果,你直接查看CPU/GPU的使用只能通过检查你应用的帧频了。MT类可以让你检查项目的帧频,还有内存使用报告和内存跟踪。

 

处理cacheAsBitmap 和cacheAsBitmapMatrix

使用DisplayObjectcacheAsBitmap属性可以大幅度提高性能(和内存),只要DisplayObject不经受需要频繁更新位图的改动。换句话说,DisplayObject在某种程度上不改变外观只是改变它在舞台上的位置。如果频繁更新位图,性能会降低。

 

你可以经常改变位图缓存,仍然可以看到性能上的收益,这取决于几个因素,但不要太惊讶,最重要的因素是,你是如何经常改变位图的。

 

无论如何,用MT类测试一个指定的工程,然后看看用位图缓存和不用有什么差别。(当决定是否对那些不需要位图改变的显示对象使用位图缓存时要不加思考的就使用!)

 

如果你有一个显示对象(如影片剪辑),你想使用位图缓存属性,加上这句:

 

mc.cacheAsBitmap = true;

 

即使你改变显示对象的大小、倾斜、透明度和或者旋转(但不改变影片剪辑的帧数),然后发布到移动设备,使用位图缓存也是能提升性能的。

 

尤其是,当把一个工程发布到移动设备时,你可以启用cacheAsBitmap并分配catheAsBitmapMatrix属性,完成后可大幅提升性能,像这样:

 

mc.cacheAsBitmap = true;
mc.cacheAsBitmapMatrix = new Matrix();

 

不要使用默认单位矩阵。以后你就会知道有几个原因促使你使用这个属性而不是用默认矩阵。

 

Stage blitting(我不知道把它翻译为“阶段块传输”还是“舞台块传输”)

 

这是一个描述数据传输的术语,包括了将使用的位图最终渲染到显示屏幕上。不是将显示对象加到显示列表里,而是把像素“放在”舞台大小的位图里,然后把位图“加到”舞台上。为了更新动画,位图的像素要在一个循环里更新。尤其是在Event.ENTER_FRAME循环里,使用BitmapData类里的copyPixel()方法,将舞台大小的位图里的BitmapData属性,在动画的循环之外替换其他的bitmapData对象。

 

这个方法比直接把对象放到显示列表里复杂,但它更有效率——如果你有个没法容忍的帧频和需要高帧频的Flash应用,这个方法会非常有用。诚然,除非你想增加帧频,否则你绝对没有理由使用这个方法。

 

我比较了一个SWF文件,它10,000个正方形影片剪辑,执行运动和旋转动作,还要穿过经过舞台(可以看blit_test/blit_test_mc.fla范例)。然后我把这个文件做了一些基本的优化(可以看blit_test/blit_test_basic_optimizations.fla文件)和stage blitting(看blit_test/blit_test2文件)。

 

第一个SWF文件大概为15fps,这是不能容忍的。但是,在应用最难的技术优化比如块传输之前,几个基本的调整就可以轻松提高性能。

 

首先,我将循环倒序,这样有了一点的性能提升(看下面循环的单元),然后,更重要的是,我使用一些常量取代了一些相同的但要重复计算的变量。这些调整时性能有了稍微大点的提升(约40%),让帧频可以稍微让人接受点了,约21fps

 

使用stage blitting编码同样的显示区域,结果帧频变成了54fps,整整提升了350%

 

但是,正如我之前说的,这个技术的过程很复杂,包括下面几个方面:

 

1.初始化需要在每个Event.ENTER_FRAME事件里循环的,要在舞台上显示的位图资源(Bitmap实例,BitmapData实例和Rectangle实例)。

2.创建一个所有要显示更新数据的数组。(这步不是必须的。)

3.创建一个BitmapData对象的数组。如果你的动画在一个影片剪辑的时间轴上,这是你要每帧都存储BitmapData对象的地方(例如,使用一个sprite列表,在范例文件夹里我为每个角度的矩形都创建了BitmapData实例,这个实例可以用AS旋转。)

4.创建Event.ENTER_FRAME事件循环。

5.更新循环里的元素,将第3步里创建数组里相应的像素,复制到在第1步里创建BitmapData实例对应的地方(第2步决定使用data数组)。

 

想看更多细节,请看blit_test/blit_test2,它还包括额外的注释。

 

Stage blitting技术的负面,不是复杂的编码,而是也许在创建需要的位图是消耗大量的内存。当为类似iPad之类有很高分辨率(第一、二代1024*768,第三代2048*1536),相对低的内存(RAM)和容量(一、二、三代分别为256MB512MB1GB)的设备写应用时,这是个要严肃考虑的问题。

 

一般来说,你的游戏应消耗不多于一半的可用RAM。这指的是,不仅包括位图而是你游戏里的一切消耗。

 

 

Partial blitting

 

正如字面含义,局部复制结合了Flash显示列表和把像素复制到BitmapData对象两种方式。特别是,在舞台的每一个显示对象是位图时,把他们加入显示列表,然后像一般的显示对象比如影片剪辑那样操控就行了。把每个对象的动画复制到一个BitmapData对象的数组里。

 

 

 

例如,使用之前有正方形运动选择穿过舞台的文件例子,我把正方形和它们各种旋转,将这些BitmapData对象存放在一个数组里,放在bitmap里加入显示列表,然后在Event.ENTER_FRAME循环里操控这些bitmap就像操控任何显示对象那样(比如之前描述的影片剪辑)。最后,我将bitmapbitmapData属性分配给对应的数组元素。(看看这是如何实现的,可以复习blit_test/partial_blitting_test.fla文件。)


在我的电脑上,Partial blitting测试(24-26fps)不会像stage blitting一样快。但是这个方法为你启发了思路,因为也许在其他方面partial blittingstage blitting快。另外,partial blittingstage blitting好编码。所以呢,如果你用partial blitting技术可以得到效果好的帧频,那么它还可以减少在stage blitting里必须要做的额外工作。(就是如果能用局部复制就可以不用stage blitting了。)

 

 

 

有关Event.ENTER_FRAME 循环

 

 

 

在一个实例上,创建多个Event.ENTER_FRAME侦听器,回调多个函数,要比一个实例上创建一个侦听器回调一个函数,这个函数再调用其他函数,要稍微快那么一点点。(好绕口啊~~~~~~)


但是,这有个不同的情况:在多个对象上分别侦听Event.ENTER_FRAME,和一个对象上侦听一个相比较,使用一个对象侦听一个是多个对象拥有各自侦听器性能的大约两倍。(可以看enterframe_test_one_v_many_loops_with_different_movieclips 文件夹下的例子。)


理解For循环,while循环和do循环

 

 

 

Flash里,for的倒序循环是最快执行的循环。如果在循环里需要存储的都是相同类型的对象,一个保存所有对象引用的,使用Vector的倒序for循环是最快的。

 

 

 

如果你使用int而不是uint来迭代元素,那这三个循环都执行的都挺快。如果你递减循环变量而不是增加,那么三个循环也会一样快。(注意:如果你递减的循环变量i使用的中止条件是i>=0,并且iuint的话,你可能会触发一个没有结束的循环。)

 

 

 

如果你使用的是变量或常量作为循环结束的标志而不是表达式或对象属性,那么三个循环一样快。因为初始条件仅需要评估一次(而不是每次循环迭代都要判断),在任何循环里循环里,使用判断式或对象属性作为初始条件都没有大的差别。


任何不会影响循环的内容都应该放到循环的外面。这包括在循环外定义对象(看重用对象的单元),有时在循环里使用新的构造函数可以放在循环外面,如果结束条件是个表达式,应该在循环外算出来。


我曾看过这种说法,对每一个有个下个对象引用的对象循环(类似链表),要比一个数组存储所有对象引用的循环快。在我的测试结果显示,这是不对的。


使用数组比先初始化再使用要快和容易。使用Vector而不是数组,当然要更快了。(见for_loop_v_sequential_loop 文件夹下的例子。)


所有的这些建议可能在很多情况下没什么很大差别。但是,如果你的代码要利用一切可以利用的资源,或者你的工程里有数量惊人的迭代,这些细节值得你参考。


禁用鼠标交互

 

影片剪辑和sprite可以和鼠标交互。即使你没有为鼠标交互编任何代码,当这些对象存在时Flash Player会检查鼠标交互。所以你可以禁用一些不需要的交互拯救一点CPU资源。

 

 

 

当你注意到性能问题,鼠标滑过舞台时(或者你的电脑风扇加快转速),这个策略非常有用。禁用鼠标交互可以提升性能还可以让你的电脑风扇安静点。


在测试时,我看到当禁用所有影片剪辑的鼠标事件后,帧频增加了2 1/2倍,这个测试代码在mouse_interactivity 文件夹下。


移除事件侦听器

 

 

 

即使最新版本的Flash Player出现了两个功能:当对象被垃圾回收后移除侦听器,和强引用侦听器不再延迟垃圾回收。你仍然要尽可能明确地移除所有的事件侦听器。侦听器越是迅速的移除掉,被占用的CPU资源越少。另外,你可能不知道你装了哪个版本的Flash Player,老版本是没有垃圾回收对象的——即那些对象是弱引用侦听器。不要依赖最新的Flash Player功能,而要踏实优化自己的糟糕代码。

 

 

 

 

有关Stage3D

 

 

 

Stage3D是基于GPU的显示渲染模型,它是Flash Player11版本发布的。这个模型对3D渲染特别有用,但是使用例如Starling的框架也能服务于2D显示。

 

 

 

因为原本CPU承担了全部的渲染显示工作,(当运行一个程序时CPU也要做其他工作),而现在GPU承担了一部分渲染工作,就可以让CPU有更多的空闲做其他工作。这样的利用极大的提高了设备性能。

 

 

 

想看Stage3D内容,你必须使用Flash Player11或更高版本。想看Stage3DAPI,你需要用Flash Player11或更高版本发布SWF文件。如果你使用Flash Professional CS6工作,那它已经全部设置好了。如果你用的是Flash Professional CS5CS5.5,你可以更新Flash安装文件使之可以发布Flash Player11。更多的细节,可以看Rich Galvan写的名为Adding Flash Player 11 support to Flash Professional CS5 and CS5.5博客。

 

很不幸,使用Stage 3DAPI非常困难。但是,有几个免费开源的框架可以生成使用Stage 3D所需的最基本的代码。

 

 

 

其中之一就是Starling,被用来开发2D游戏。它简单易学并且高效简化了Stage3D的复杂性。Starling API可以在Starling框架参考网站里寻找。

 

 

 

我测试了Starling来看它和blittingpartial blitting相比较如何。在某些情况下,Starling表现的比这两种blitting要不好。事实上,他表现的比没有优化的10,000个正方形影片剪辑的测试还要糟糕。

 

 

 

但是,在Starling测试里,如果你不选择允许编译选项,那么这小小的改变可以使帧频快两倍,输出的SWF文件可以比得上没有优化的10,000个正方形测试。但是这个结果依然让人失望,部分的问题在于,我使用编译版本的Flash Player来测试时,在编译和不编译两种情况下,Starling在编译情况下表现的不好。

 

 

 

另外,10,000个正方形影片剪辑测试不能显示出Starling最好的一面。如果你使用许多包含各自时间轴动画的影片剪辑,Starling会比几乎任何你使用的简单优化技术要出色。

 

 

 

仅仅blitting优化的性能就要优于使用Stage3DStarling所带来的收益。但是blitting也许不是那么实用,因为内存需要创建所需的位图。

 

 

 

范例文件在starling_test 文件夹下。


使用Starling框架时,要遵循以下步骤:

 

 

 

1.下载Starling.swc文件。

 

2.使用以下步骤将它导入你的Flash工程链接库:

 

1)选择,文件>发布设置>脚本设置。

 

2)点击库路径选项卡,然后点击浏览,选择你下载好的swc文件的位置路径。

 

3)在“打开文件”对话框,选择你放swc文件的路径。

 

4)点击“打开”,添加starling.swc到你的链接库路径。

 

5)点击OK关闭高级ActionScript 3.0设置面板,然后再次点击OK关闭发布设置。

 

6)保存Fla文件,你就可以使用Starling了。

 

(我一般都是在builder里导入和使用的,估计这里有人看了会迷茫,我翻译的不是太好,自己多选两次就知道了,让我偷个懒吧!)

 

 

 

如果你用Stage3D发布移动air游戏(它包括了类似Starling的框架来使用Stage3D),可以设置渲染模式来指导。如果你发布的是内置HTML文件,可在发布设置里设置窗口模式进行指导。

 

 

 

你可以在Adobe Gaming site学习更多有关StarlingStage3D API的信息。

 

 

 

下一步


上面所讨论的优化技术外,开发Flash项目要提高重放性能时,还有另外两种你可以使用的最佳实践技术:

 

 

 

1.为你声明的每个变量确定类型,如果你肯花时间确定所有变量的类型,代码会执行的更快,当遇到错误时,编译显示的错误信息也更具描述性和帮助性。可以查看测试范例variables_typed_v_untyped。


2.使用Vector而不是array来存储数据信息。为了看到它的性能,可以看array_v_vector文件。

 

希望这篇文章的推荐的大纲可以帮你提高在Flash Professional里创建工程的性能。想要学习更多有关建立Flash动画,应用和游戏的信息,可以访问Flash Developer Center

 

 

posted @ 2014-08-09 22:33  全栈深入  阅读(2188)  评论(0编辑  收藏  举报