Starling的性能优化(译文)Part 1

Dodge
由于最近一直在折腾Starling相关的开发,这已经不是第一次向Starling进击了,因此也鸡贼了一些,今天静下心来仔细细读了一遍官方的优化建议,终于使自己手上的项目运行在一个比较理想的性能指标上了,故而饮水思泉,想翻译原文一篇,供大家一起研究。

原文地址:Performance Optimization

Starling的性能优化

尽管Starling仿造了Flash显示列表的经典结构,但是在这表象的背后却蕴含着巨大的不同。因此,想要使程序达到最佳的性能,你首先应该了解其架构中的一些关键性概念。下面是一个最佳实践列表,你可以按照这个顺序实践来使你的游戏运行得尽可能地快,哦耶。

与标准AS3相关的建议

永远要以发布版本(release build)作为性能比照的依据

首先最重要的第一条法则是:在想测试性能的时候永远要以发布版本作为标准。与常规的Flash项目不同,使用Stage3D框架构建的程序发布版本与测试版本的性能存在巨大的差异。速度上简直是天差地别;取决于你的程序最终运行的平台是什么,这一点可以很容易地从调试版本(debug build)的运行时的帧频看出来。

  • 在Flash Builder中,可以通过点击菜单“项目—导出发布版”来实现导出发布版本。
  • 在Flash Develop中,选择“发布”配置选项,并构建项目,然后,在执行“PackageApp.bat”脚本时,选择“ipa-ad-hoc”或者“ipa-app-store”选项。
    检查你的硬件

要确保Starling确实在使用GPU做渲染。要确认这点很容易:如果Starling.current.context.driverInfo中包含“Software”字段,这时Stage3D就处于软件回退(software fallback)模式下,否则,它就是在使用GPU做渲染。
此外,很多移动设备可以运行在一种“节能模式”下。请确认关闭这个模式后再做性能测试。

使用Adobe Scout

最近(已经不是最近了),Adobe发布了一个Amazing的性能调试工具,叫做Scout。它即灵巧又易用:只要在编译程序时,开始-advanced-telemetry(遥测数据)选项,然后在加载你的游戏之前打开Scout就可以了。在移动设备上也灵哦!

从这里获得Scout gaming.adobe.com(目前仍然免费)
仔细看看这个视频教程来了解它的大概情况。视频教程
或者,你可以从这里获得一个较为详尽的相关描述。Getting Start with Scout

对外部加载的图片做异步解码

当你使用Loader加载外部图片资源时,比如说PNG或者JPEG,利用这个图片资源作为Texture使用时需要对其进行解码操作。这个操作通常发生在主线程中,可能会造成你的程序在加载图片时非常卡顿。这时,你可以将图片的解码策略设置为 ON_LOAD,这样,解码操作就会在后台线程中被处理。

 loaderContext.imageDecodingPolicy = ImageDecodingPolicy.ON_LOAD;  
 loader.load(url, loaderContext);  
`</pre>
关于这个问题更多消息请访问这里,[LoaderContext documentation](http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/LoaderContext.html#imageDecodingPolicy)

语法技巧

ActionScript 3已经被证实暗藏许多可能降低性能的疑难杂症,因此最好避免这些情况的发生。下面的几点非常重要:

关于循环
尽量避免使用“for each”循环语法,多使用经典的“for i”语法。此外,要注意,循环条件是每次都要被执行的,所以把判断值存放在一个变量中是最快的办法。
<pre>` // 慢  
 for each (var item:Object in array) { ... }  
 // 不错  
 for (var i:int=0; i&lt;array.length; ++i) { ... }  
 // 最快
 var length:int = array.length;  
 for (var i:int=0; i&lt;length; ++i) { ... }  
`</pre>
避免实例化对象
要避免创造一大堆临时变量。它们会耗费大量的内存,需要垃圾回收机制来处理,这会造成运行时的卡壳。
<pre>` // 翔代码
 for (var i:int=0; i&lt;10; ++i)  
 {  
   var point:Point = new Point(i, 2*i);  
   doSomethingWith(point);  
 }  
 // 不错
 var point:Point = new Point();  
 for (var i:int=0; i&lt;10; ++i)  
 {  
   point.setTo(i, 2*i);  
   doSomethingWith(point);  
 }  
`</pre>
访问Array或Vector元素
当你想获取一个Array或者一个Vector的某一元素时,要小心:当目标下标是一个通过计算获得的结果时,永远要记得把它转为int型。出于某种原因,这样做会让AS3处理得更加快。
<pre>` // 翔代码
 var element:Object = array[10*x];  
 // 不错
 var element:Object = array[int(10*x)];