`
airfans
  • 浏览: 122418 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

构件性能优化,高效的AIR应用程序 之Framerate 细节处理

阅读更多

如何构件性能优化,高效的应用程序无论利用那种技术,都会是一个复杂的问题,尤其是构件大型的应用,会有很多影响到系统性能,效率的因素。比如,程序的架构是否合理,是否有冗余逻辑造成效率降低,核心算法是否优化,是否关注代码细节的合理处理,等等,很多适用于其他技术的经验,方法也应该适用于构建 AIR 应用程序。那么,有没有一些针对AIR 应用程序相对特殊的地方呢?
 
首先引入一个概念,帧频(Framerate)。我们都知道电影,动画都是一帧一帧的播放的,通常以每秒 24 帧作为一个基础,因为这是适合人类视觉感光频率的,当然在高清,流媒体等应用领域帧频会不同于这个值。我们所构建的基于 flash 的 AIR 应用程序都基于这个原理,即便看似不变的界面也是一帧一帧渲染出来的,系统默认设置值也是 24 帧每秒。毋庸置疑,每渲染一帧,都会消耗一定 CPU, 内存资源。
Framerate 在 flash/AIR 应用中的位置就像心脏在我们身体中一样,同一个人,在安静或睡眠时心率减慢,运动时或情绪激动时心率加快。人必须保持的保持在一个合理的心率范围,就像美洲豹如果以时速 120 公里追赶猎物,超过 30 秒还没有抓到的情况下就必须止步放弃一样,长时间高速运转就会给身体带来损害。 Framerate 道理也是一样,如果长时间维持在一个高帧频率必定会带来额外的系统消耗。

Arno在他的博客中提出了几个最佳实践,归为以下几点:
1 ,尽量使用低的帧频率
2 ,动态设置帧频率已适应动画渲染需要
3 ,不再必须的情况下不要使用   Event.ENTER_FRAME handler 
4 ,尽量介绍少用 Event.ENTER_FRAME 和Timer 的个数

对于以上几点可以再做出以下补充解释:
1 ,如果你所构建的应用程序是以数据驱动 , 实现商务逻辑为主,并且展现层上没有特别多的动画, transition, 或是   effect,  可考虑降低整体帧频率,如设置为 7 帧每秒,正常情况下,可降低 CPU 1%- 5% ( 在我的 MAC 上已证实 ) 。   同时,如果应用程序的 user interaction  不是很多的情况下,当应用程序处于AIREvent.APPLICATION_DEACTIVATE  时,降低帧频率至 0 ,也可大大降低 CPU  使用率。
如果有 Video playback, 或是大量 animation  的时候,可考虑设置一个开关机制,需要的时候开启开关,动态把帧频设高,播放完毕后再恢复省资源模式。
2 ,如果在不同的 timer  中,能找到之间的逻辑关系,则减少独立 timer 的个数,用逻辑去实现与之相关联 timer 的触发。
3 ,我在调试过程发现可设置一个用 timer 检测的简易可视帧频率,这样能科学验证,且心理看得踏实,代码如下供参考:

<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml " layout="absolute" creationComplete="init()" 
width="320" height="480" 
verticalScrollPolicy="off" 
horizontalScrollPolicy="off" 
borderStyle="none" 
showGripper="false" 
showStatusBar="false" 
showFlexChrome="false" 
backgroundColor="#FFFFFF"> 
  
<mx:Script> 
                <![CDATA[ 
                import mx.events.AIREvent;    
                private var fpsCounter : uint; 
                private var timer : Timer; 
                public static const ACTIVE:int = 24; 
                public static const INACTIVE:int = 1; 
  
                private function init() : void 
                { 
                    timer = new Timer(1000); 
                    timer.addEventListener( TimerEvent.TIMER, onTimerEvent ); 
                    timer.start(); 
                    fpsCounter = 0; 
                    this.addEventListener(Event.ENTER_FRAME, onFrameEnter); 
                    this.addEventListener(AIREvent.APPLICATION_DEACTIVATE,onDeactivate); 
                    this.addEventListener(AIREvent.APPLICATION_ACTIVATE,onActive); 
                } 
                                                
                 private function onActive(event: Event):void 
                 { 
                      this.stage.frameRate = ACTIVE; 
                      setFPS.text = Math.round(stage.frameRate).toString() + " fps";  
                 }                                                                                                       
                 private function onDeactivate(event: Event):void 
                 { 
                      this.stage.frameRate = INACTIVE; 
                      setFPS.text = Math.round(stage.frameRate).toString() + " fps";  
                  } 
                  private function onFrameEnter( event : Event ) : void 
                  { 
                      fpsCounter++; 
                      trace("enterframe"); 
                   } 
                                                
                   private function onTimerEvent( event : Event ) : void 
                   { 
                        curentFPS.text = fpsCounter.toString()+ " fps"; 
                        fpsCounter=0; 
                    } 
                                
                    public function changeFrameRate(delta:Number):void 
                    { 
                         stage.frameRate = stage.frameRate + delta; 
                         setFPS.text = Math.round(stage.frameRate).toString() + " fps";                                  
                     } 
                     ]]> 
                </mx:Script> 
                
  
    <mx:Image id="logo" source="@Embed(source='assets/logo.jpg')" y="195" x="102"/> 
  
    <mx:Button id="decreaseButton" x="27" y="329" label="-" width="67" height="74" fontSize="60" 
                click="changeFrameRate(stage.frameRate > 20 ? -5 : -1);"/> 
  
    <mx:Label text="Current FPS" color="#797979" width="105" textAlign="center" fontSize="14" x="37" y="177" fontWeight="bold"/> 
    <mx:Label text="24 fps" color="#797979" width="96" textAlign="center" fontSize="14" x="167" y="177" id="curentFPS"/> 
  
    <mx:Button id="increaseButton" x="217" y="329" label="+" width="74" height="74" fontSize="60" 
                click="changeFrameRate(stage.frameRate >= 20 ? 5 : 1);"/> 
  
    <mx:HBox height="40" verticalAlign="middle" bottom="0" left="0" right="0" horizontalAlign="center" horizontalGap="0"> 
    </mx:HBox> 
    <mx:Label text="Set FPS" color="#797979" width="96" textAlign="center" fontSize="14" x="26" y="149" fontWeight="bold"/> 
    <mx:Label text="24 fps" color="#797979" width="96" textAlign="center" fontSize="14" x="167" y="150" id="setFPS"/> 
    <mx:TextArea x="10" y="10" width="300" color="#797979" height="78" borderStyle="none" fontSize="14"> 
    <mx:text>Compare the CPU usage of this application when it is in different FPS setting.</mx:text> 
    </mx:TextArea> 
</mx:WindowedApplication> 

 

 

     demo截图


4 ,还有很多影响 AIR 性能效率的小细节   如 number of display objects on stage (http://bugs.adobe.com/jira/browse/FP-1149)   等等。欢迎大家一起来探讨!


-瓶子

 

  • 大小: 83.7 KB
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics