如何降低应用程序对内存和CPU的消耗,提高程序运行效率(一)

         在之前我们开发游戏一般都只是创建桌面应用程序,而不必去太多关注内存和CPU的使用,因为电脑的基本配置就可以胜任程序的运行。但是在将我们写好的桌面应用程序发布到手机上时,基本上会卡死。因为虽然我们最新的手机iPhone及Android提供了相当高的处理器及更多的内存,但是相比电脑上运行应用程序仍然是小巫见大巫。那么如何才能提高应用程序对内存及CPU的消耗呢?

        通常摆在我们所有程序猿面前的一个问题是:我们在编程时应该更关注那一个问题——内存还是CPU资源?因为这两者往往是不可能同时达到的。

        下面我们就通过:1.重用对象;2.缓存位图;3.优化帧速率;4.使用GPU渲染,这四个方面来优化内存和CPU使用。

一、重用对象

         我们在处理对象时往往是创建并移除他们,但是任何时候实例化一个对象代价是相当大的,但是如果我们很方便的使用对象池来实现对象的重用,则会大大提高其使用效率。

         1.使用条件:应用程序需要不断地创建并处理对象,这是我们可以考虑使用对象池。

         2.原理:当创建对象池时,在应用程序启动时将会创建一起对象,这样应用程序不需要再创建新对象,而是从对象池中请求并使用它们。当应用程序完成处理这些实例之后,它将停止使用并删除对它们的引用,但是并不将他们设置为null,这时已经对象返回对象池中,便于以后的使用。

        3.示例对象池,在以后程序中使用时就可以直接使用并重用其中的对象。

package
{
import com.zxh.animal.Dog;//狗对象的封装类
public final class DogPool{
       private  static var  _pool:Vector.<Dog>;//创建一个狗的对象数组作为对象池
        private  static var  _maxCount:int;//对象最大数目
        private static var  _counter:int;
       private  static var  _growthValue:int;//增加的数目
        
        public static function init(initialCount:int , growthValue:int):void{
            var i:int = initialCount;
            //设置相关属性
            _maxCount = initialCount;
            _counter = initialCount;
            _growthValue = growthValue;
            //创建对象池,其中含有initalCount个对象
            _pool = new Vector.<Dog>(initialCount);
            //创建Dog对象
            while( --i > 0){
                _pool[i] = new Dog();
            }
        }
        
        public static function getDog():Dog{
            var i:int = _growthValue;
            if( _counter > 0){
                return = _pool[    --_counter];
            }
            while( --i > 0){
                _pool.unshift( new Dog());
            }
            _counter = _growthValue;
            return getDog();
        }
        
        public static function disposeDog(dog:Dog):void{
            _pool[ _counter++ ] = dog;
        }
    }
}

二、缓存位图

在手机应用程序中渲染图形的第一原则是尽可能缓存一切内容,重新绘制的开销更大,因此只有在必要的时候才进行渲染。

缓存位图需正确理解和使用以下三种属性:1.cacheAsBitmap;2.cacheAsSurface;3.cacheAsBitmapMatrix。

1.cacheAsBitmap:

        a.功能:缓存屏幕外位图,使得可以重复使用它而不需要多次重建位图。消除了渲染现实对象的需求。

       b.何时使用(=true):对于不需要应用变换效果的现实对象启用。

       c.何时避免启用:如果需要改变现实对象的alpha属性、旋转、缩放等操作时,不必使用该属性。

                                    如果现实对象的内容频繁改变,则不必使用该属性。

2.cacheAsSurface:

       a.功能:忽略了重新渲染现实对象的需求。矩阵变换,例如缩放和旋转,应该应用现在缓存对象的外部,而不应该实现为缓存对象的子对象。如果这样GPU(Graphical

                     Progress Unit,图形处理单元)将处理它。

      b.何时使用(=true):对于需要在其上应用变换的现实对象启用。如果在容器现实对象内部动画其他现实对象,则应该对容器现实对象启用。

      c.何时避免使用:如果现实对象的内容频繁改变或现实对显的衍生对象也频繁改变,则不要使用该属性。

3.cacheAsBitmapMatrix:

      a.功能:缓存x、y、旋转、缩放和偏斜属性。

      b.何时使用(=true):适用于非定期更新的现实对象。

      c.何时避免使用:如果要修改alpha、颜色属性或者子sprite矩阵,则不需要使用该对象。因为它不仅需要绘制,同时还需要缓存,这样讲减慢渲染速度。

三、优化帧速率

一般情况下我们需要尽可能的降低帧速率,确保性能最优。即设置Stage.framRate(在Flex中设置WindowsApplication.framRate)

设置规则:1.如果程序内部没有使用动画,择其速率一般为4~12帧。

                   2.如果程序内有动画,则使用20~30帧,但不要超过30帧。

                   3.如果程序运行视频,则不必调整速率,视频将会接管这速率,自己调整到最佳。就算我们人为地设置改变其速率也没有效果。

四、GPU渲染

不管我们再Android或者iPhone平台上运行应用程序,其都支持GPU硬件加速,GPU处理图形渲染可以很大程度的提高性能。

启用GPU渲染我们必须在应用程序的配置文件(应用程序名.xml)中设置其renderingMode属性设置为gpu,如下:

<renderMode>gpu</renderMode>

          但是我们必须知道启用GPU渲染能够处某些特定的任务,但是也不会处理一些其他特定的任务。

          GPU不支持如下的操作:

1.滤镜

2.PixelBender(Pixel Bender是Adobe推出的一个高性能的图像视频处理技术。它能跨平台地使用CPU, GPU来对图像和视频应用滤镜和效果,在不了解底层硬件的前提下,我们也可以利用它实现自己的图像处理算法,并良好地运行在各种不同CPU、GPU型号的机器上。)

3.混合(alpha、擦出、重叠、硬光、加亮、和加暗模式)。

4.大于1024*1024的结构尺寸。

5.视频。

6.使用软键盘时调整视角以显示文本输入字段。

*特别注意:在IOS上的GPU渲染仅限于渲染位图、实心阴影以及其cacheBitmap属性设置为true的现实对象。

之后还有其他关于优化cpu和内存的使用注意事项,请关注我的如何降低应用程序对内存和CPU的消耗,提高程序运行效率(二)

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注