`

关于优化

阅读更多

1. Avoid the new operator when creating Arrays

 

避免用 new关键字来创建数组
 
var
 a = []; <推荐使用>

NOT:   <不推荐使用>

 
var
 a = new
 Array
(); 

2. Arrays are expensive to create, do so conservatively

数组很耗性能,所以应尽量少创建些数组

 
var
 vanityCollection01 : Array
 = new
 Array
(); 
var
 vanityCollection02 : Array
 = new
 Array
(); 
var
 vanityCollection03 : Array
 = new
 Array
(); 
var
 vanityCollection04 : Array
 = new
 Array
(); 

3. Fastest way to copy an array:  

复制数组最快的方法,即耗时最少!

 

 
var
 copy
 : Array
 = sourceArray.concat
();   

4. Setting values in Arrays is slow

给数组赋值是非常耗时的

 
employees.push
( employee ); 
employees[2] = employee; 

5. Getting values from Arrays is twice as fast as setting

取得数组里的值的速度是给数组赋值的两倍 即取值比赋值块!

 
var
 employee : Employee = employees[2]; 

6. Use static for properties methods that do not require an object instance  

使用静态方法创建某个对象,不需要创建该类的实例(貌似是屁话,会编程的都知道!)

 
StringUtils.trim( "text with space at end 
" ); 
Class definition: 
package 
{ 
     public
 final class
 StringUtils 
         { 
          public
 static
 function
 trim( s : String
 ) : String
 
          { 
               var
 trimmed : String
; 
               // implementation... 

               return
 trimmed; 
           } 
      } 
} 

7. Use const for properties that will never change throughout the lifecycle of the application  

常量 (用const 声明的量)的值在程序的整个生命周期中都不会变. (又是一句屁话)

 
public
 const APPLICATION_PUBLISHER : String
 = "Company, Inc.
"; 

8. Use final when no subclasses need to be created of a class  

当某个类不需要子类继承时,对该类使用final关键字,阻止被继承

 
public
 final class
 StringUtils 

9. Length of method/variable names doesn't matter in ActionScript 3.0 (true in other langs)  

方法名属性名的长短不会对程序有任何影响!原因是只有他们的值在才进入avm进行编译(这也是为什么我们进行反编译后,发现变量名怪怪的,经常是带"_" 这个符号!这是计算机自动分配的)

 
someCrazyLongMethodNameDoesntReallyImpactPerformanceTooMuch(); 

10. One line assignments DO NOT buy any performance (true in other langs)  

在一行写多个语句不会对程序造成任何影响

 
var
 i=0; j=10; k=200; 

11. No difference in memory usage between an if statement and a switch statement  

if语句和switch 在访问存储方面没有任何区别!

 

但是我觉得switch的效率好像高一些!

 
if
 ( condition ) 
{ 
     // handle condition 

} 

IDENTICAL MEMORY USAGE:  

相同的访问储存:

 

 

 
switch
 ( condition ) 
{ 
     case
 "A
": 
         // logic to handle case A 

     break
; 
      
     case
 "B
": 
         // logic
 to handle case B  

     break
; 
} 

12. Rank your if statements in order of comparisons most likely to be true  

将if语句里概率最大的(即最容易出现的情况)放在前面

 
if
 ( conditionThatHappensAlot ) 
{ 
     // logic to handle frequently met condition 

} 
else
 if
 ( conditionThatHappensSomtimes )  
{ 
     // handle the case that happens occaisonally 

} 
else
  
{ 
     // handle the case that doesn&#8217;t happen that often 

} 

13. AVM promotes int to Number during calculations inside loops (VM has been changing, from 9 to 10, so int, uint and number conversions aren't as slow as they used to be.)

AVM机建议在for循环尽量使用Number类型!

14. Resolve issues of promotion, unknown, or incorrect object types

尽量使用明确的变量类型 即其type要明确!这会提高程序的效率!(thinking in java 第四版里讲过这)

15. Use uint sparingly, it can be slow (VM has been changing, from 9 to 10, so int, uint and number conversions aren't as slow as they used to be.)

尽量少使用uint类型,因为它的速度很慢,最慢的!最好只在涉及到颜色值时才使用它。

 
var
 footerHex : uint = 0x00ccff; 

16. Use integers for iterations  

在for循环里使用int类型的变量

 

 
(var
 i: int
 = 0; i < n; i++) <推荐>
NOT for
 (var
 i: Number
 = 0; i < n; i++) <不推荐>

17. Don't use int with decimals  

对带小数点的数使用Number类型

 
var
 decimal : Number
  = 14.654; 

NOT:  

 
var
 decimal : int
  = 14.654;  <不推荐>

18. Multiply vs. Divide: instead of 5000/1000 use: 5000*0.001

尽量使用乘法,用乘法代替除法

 

19. Locally store function values in for and while statements instead of repeatedly accessing them  

对一些类型转换及角度换算,在for循环外面使用而不要在 {}里使用

 

 
for
 (..){ a * 180 / Math
.PI
; }  
declare: toRadians = a*180/Math
.PI
; outside of the loop 

20. Avoid calculations and method calls in loops  

尽量在for循环里少做些运算

比如数组的长度length应该在外面计算!

 

 
var
 len : int
 = myArray.lengh;  
for
 (var
 i=0;i<len;i++){}  <推荐>

NOT:

<不推荐使用>

  
for
 (var
 i=0;i< myArray.lengh;i++){ } 

21. Use RegEx for validation, use string methods for searching  

使用RegEXp对象进行结果验证,而应该使用String类型的方法进行搜索 替换等

 
// postal code validation example using regular expressions 

private
 var
 regEx:RegExp = /^[A-Z][0-9][A-Z] [0-9][A-Z][0-9]$/i; 
private
 function
 validatePostal( event : Event ) : void
 
{ 
     if
( regEx.test( zipTextInput.text
 ) ) 
     { 
          // handle invalid input case 

      } 
} 
 
// search a string using String methods 

var
 string : String
 = "Search me
"; 
var
 searchIndex : int
 = string.indexOf
( "me
" ); 
var
 search : String
 = string.substring
( searchIndex, searchIndex + 2 ); 

22. Reuse objects to maintain a “memory plateau” DisplayObjects, URLLoader objects

尽量的重复使用对象,使内存维持在一个较低的水平!

 

23. Follow the Flex component model:  

 
createChildren(); 
commitProperties(); 
updateDisplayList(); 

24. Only use Datagrids as a last resort (make sure you can’t implement in a regular List first)

少使用DataGrid  很占内存

25. Avoid Repeaters for scrollable data

 

26. Avoid the setStyle() method (One of the most expensive calls in the Flex framework)

少使用setStyle方法它很耗内存

27. Using too many containers dramatically reduces the performance of your application  

过多的的使用容器会降低程序的灵活性

 
<mx:Panel> 
    <mx:VBox> 
        <mx:HBox> 
            <mx:Label text
="Label 1
" /> 
             <mx:VBox> 
                  <mx:Label text
="Label 2
" />  
              </mx:VBox> 
              <mx:HBox> 
                  <mx:Label text
="Label 3
" /> 
                  <mx:VBox> 
                      <mx:Label text
="Label 4
" /> 
                  </mx:VBox> 
              </mx:HBox> 
          </mx:HBox> 
      </mx:VBox> 
</mx:Panel> 

28. You do not need to always use a container tag as the top-level tag of components Totally valid component, no top level container needed:  

对一些这样的组件(在容器里设置一些属性及组件),  而应该用自定义组件代替,如下:

 

 
<mx:Image xmlns:mx="http://www.adobe.com/2006/mxml
"  
     source="avatar.jpg
" width
="200
" height
="200
" /> 

29. Remove unnecessary container wrappers to reduce container nesting

去掉一些不必要的嵌套容器,即尽量少使用容器 30,31例子是举例说明

30. Avoid: The VBox container inside an tag, (eliminates redundancy)  

 

 <推荐>

<mx:Panel> 
    <mx:Label text
="Label 1
" /> 
    <mx:Label text
="Label 2
" /> 
</mx:Panel> 
 
<不推荐,应将多余的VBox容器去掉>

<mx:Panel> 
     <mx:VBox> 
        <mx:Label text
="Label 1
" /> 
        <mx:Label text
="Label 2
" /> 
    </mx:VBox> 
</mx:Panel> 

31. Avoid: VBox container inside an mx:Application tag, (eliminates redundancy)  

<推荐>
 
<?xml version
="1.0
" encoding="utf-8
"?> 
<mx:Application
 xmlns:mx=http://www.adobe.com/2006/mxml> 

    <mx:Label text
="Label 1
" /> 
    <mx:Label text
="Label 2
" /> 
</mx:Application
> 

NOT:   <不推荐>

 
<?xml version
="1.0
" encoding="utf-8
"?> 
<mx:Application
 xmlns:mx=http://www.adobe.com/2006/mxml> 

    <mx:VBox> 
        <mx:Label text
="Label 1
" /> 
        <mx:Label text
="Label 2
" /> 
    </mx:VBox> 
</mx:Application
> 
 

32. Set the recycleChildren property to true to improve a Repeater object's performance   (re-uses previously created children instead of creating new ones)  

 
<mx:Script> 
    <![CDATA[ 
        [Bindable] 
        public
 var
 repeaterData : Array
 = ["data 1
", "data 2
"]; 
    ]]> 
</mx:Script> 
 
<mx:Repeater id="repeater
" dataProvider="{repeaterData}
">  
    <mx:Label text
="data item: {repeater.currentItem}
"/> 
</mx:Repeater> 

33. Keep framerate set at 60 fps or lower  

<将帧频设置为60或者低于60>

 
<?xml version
="1.0
" encoding="utf-8
"?> 
<mx:Application
 xmlns:mx=http://www.adobe.com/2006/mxml  

    frameRate="45
"> 
</mx:Application
> 

34. Avoid multiple display manipulations per frame

<每帧不要显示太多的显示对象>

35. Code against ENTER_FRAME events instead of Timer events 

 多使用ENTER_FRAME, 少用Timer    因为Timer很耗内存

用getTime()可以解决计时不准确的问题  另外Timer 也不是很精确

 

<推荐:>

 
public
 function
 onEnterFrame
( event : Event ) : void
 
{ 
} 
private
 function
 init
() : void
 
{ 
     addEventListener( Event.ENTER_FRAME, onEnterFrame
 ); 
} 

NOT: <不推荐>

 
public
 function
 onTimerTick( event : Event ) : void
 
{ 
} 
private
 function
 init
() : void
 
{ 
     var
 timer : Timer = new
 Timer(); 
     timer.start
(); 
     timer.addEventListener( TimerEvent.TIMER, onTimerTick ); 
} 

36. To defer object creation over multiple frames  use: 

 通过多帧来创建对象,而不要在一帧内全部创建完  

 
<mx:Container creationPolicy="queued
"/>  

37. Alpha = 0 is not the same as visible = false (Objects marked invisible are passed over)

  alpha值为0并不表示其不可见  一样的占内存!应使用 visible =false

 
loginButton.visible
 = false
; 

NOT:  

 
loginButton.alpha = 0; 
(原文http://www.insideria.com/2009/04/51-actionscript-30-and-flex-op.html
 
为了使上面的更好理解 下面是我对Java的部分理解对上面有帮助:
Java基础:
 

List 类是容器 用来存放序列 。 Maps 是容器,它是关联数组 。 Sets 类 也是容器,保存每种类型对象的一种 。 List的两种数组: ArrayList :访问数组里阿妈的任何一个数组的时间都是一样的 。然而LinkedList:越深的所以访问所需的时间越长。 插入一个元素到数组里。使用ArrayList的时间较长,LinkedArray的时间较短 。 具体化的数组有利于回收: ArrayList<Shape> shapes = new ArrayList<Shape>(); 相应的as里 var shapes :Vector.<Shape> =new Vector.<Shape>(); 局部变量都是保存在stack里! 动态创建的对象都保存在堆里(heap也就是a pool of memory <记忆池>),动态对象一般都是运行时创建的 堆heap分配给动态变量所需的时间比在栈stack里分配内存要的时间长.堆heap内存分配依赖于它的存储机制。动态分配机制更复杂和多变化 。

Java只用动态(dynamic)分配存储 :即:我们创建新的对象(动态对象)需要new 构造器。他们都存储在堆heap里 。  AS类似 。

在栈里创建的对象(局部变量),编译器能决定它存在多长的时间,然后自动的销毁它 。 然而堆里heap里的对象,编译器不知道它的生命周期(即不知道什么时候它该销毁),在C++里,我们要人为的编程去销毁它(堆heap里的对象)。在java里 存在GC(垃圾回收器)能很好的防止内存泄露 。

Register(寄存器):它的存储速度是最快的,速度第一 。因为它和其他的存储方式不同,它位于处理器内部。但是寄存器的数量有限!只有当其需要时才分配,我们 不能直接 操作控制寄存器 .但是C++可以将寄存器分配给编译器 。

 

栈stack :它位于一般的随机访问存储器里(RAM)。栈里能够快速高效的分配内存,它的速度只比Register(寄存器)慢,速度第二 。stack里的变量都具有确定的生命周期! 这限制了它的多样可变性。局部变量全部存储在stack里,生命周期到了自动销毁!此外,对象Object的引用也保存在栈stack里 ,而对象Object本身则保存在堆heap里。

堆heap : 它也位于访问存储器里(RAM).所有的JAVA Object对象都位于堆heap里。与栈stack不同的是,heap的优点在于编译器不需要知道存储的的对象在堆heap上保存多长的时间 !因此这增加了堆heap存储的多样性。当你需要一个对象时,只需new 一下。堆heap就自动给该对象分配内存 。注意:在堆heap上分配内存消耗的时间比在栈stack里消耗的多 。

Constant 存储:常量存储 .位于只读存储器(ROM)。常量不可更改!

Non-RAM存储: 程序外部数据,当程序未运行时就存在。其主要有两种:   @1 :  流对象 :对象被转化为字节流,然后传输到其他的机器上。  @2 : 持续存储对象: 这些对象被写入磁盘。当程序终止时依然存在 。 上面两种存储方式都是将对象转化为其他媒介。这些对象能够被还原RAM(随即访问存储器)里的对象。

对于一些基本类型:我们不需要用引用和new   而是直接持有该值。 下面是一些基本类型: boolean char  byte  short int long float  double void    这些类型是直接持有值而不是引用 。并且这些值存储在stack里

 
 
 
下面是关于int Number  uint的比较:
注意:在AVM2里,int uint类型都首先转化为Number类型 再进行计算
在for循环里遍历 16777215次,使用int Number uint类型分别作为其遍历的变量的类型 <即 for(var i:*){},i的三种类型造成的结果>
   下面是耗时的结果:
   int: 24-26ms
Number: 31-36ms
uint: 105-225ms
上面说明了uint速度最慢   int 比Number快一点
 
下面我们再在for()循环里加入一些其他的语句
我们设置定义的变量类型为 Type   其有三种情况:  int Number uint
当这样在for循环里定义变量   :
var a :Type =0
耗时结果平均值:
  int: 24-45ms
Number: 24-36ms
uint: 25-37ms
上面说明uint 最慢   int 比Number快一点点
 
当我们定义小数时:
var  a :Type=0.5;
耗时结果:
int: 56-83ms
Number: 26-43ms
uint: 57-92ms
上面显示Number类型的耗时最少!
 
 
 
当我们将数字分割:
 var  a:Type=i/2
耗时结果:
int: 60-105ms
Number: 34-64ms
uint: 184-278ms
上面显示Number耗时最少 速度最快 。 说面Number类型的量杯分割时的速度最快,  也就是说Number类型的的量进行除法运算耗时最少!
 
 
当进行乘法运算:
 var a:Type= 2*i
耗时结果:
int: 78-129ms
Number: 39-64ms
uint: 207-280ms
上面说明Number耗时最少  即进行乘法运算时选着Number类型
 
 
进行加法运算:
 
var a:Type= i+ 2;
耗时结果:
int: 31-49ms
Number: 44-55ms
uint: 85-113ms
 
上面int类型只是比Number类型快一点点
 
 
进行位运算:
 
var a:Type=i<<1;
耗时结果:
int: 31-63ms
Number: 61-114ms
uint: 71-130ms
 
int类型进行位运算结果最快
 
简单小结 在for循环条件里 for(var i:int)   我们将i 设置为int 型
在for(){}循环{} 里面的量进行乘除法时我们选择其类型为Number     进行加法运算时选择Number型或者int都可以
进行位运算时选择 int型
由上诉结果我们可以看出 我们应该尽量少用uint类型
再就是尽量用乘法代替除法 
 
 
再就是构造函数不经过 JIT技术编译!所以构造函数内的代码一般运行较慢,所以我们需要将里面的代码通过一个函数引出:比如init()
在init()初始化,而不要直接在构造函数里初始化!
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics