• 关于性能优化的以及int Number uint的比较


    A homework assignment I was recently given for a Java programming class involved a competition to see who could create the most optimized implementation of an interface which was provided by the instructor. It was a challenging and very fun assignment that I think the whole class enjoyed. I didn’t win the competition but still came out a winner because of my heightened interest in application optimization and performance tuning that I gained.

    I’m personally a pretty big fan of coding standards and have been ribbed by many developers over some of the longer method, variable and class names that I sometimes choose. I've always leaned toward the side of programming that employs standards and frameworks . Rather than spending a ton of time digging around in compiler specs and messing with GC (Garbage Collection) for reasons of performance, tuning and optimization. I was leaving this to the seasoned programmers creating the standards and frameworks I use.

    This isn’t to say I’ve never paid attention to performance and I enjoy building slow applications. It’s almost like two different worlds; the optimization world and the standards world. They don’t always agree with each other. There can sometimes be a trade off for performance over readability and organization or vice-versa. This article is meant to stand next to the Flex Best Practices articles that I authored.

    While creating my concrete implementation for the homework assignment I discovered a powerful profiling engine in NetBeans. The NetBeans profiling engine helped me understand some of the memory usage and consumption of each property, method call and object instantiation in my program. This profiler in NetBeans is very similar to the one found in Flex Builder. Both are very powerful and very useful. I've been exploring the Flex Profiler in greater detail lately as well and using it to eradicate memory leaks for a real world application I’ve been refactoring to best practices lately.

    The Java optimization homework has increased my interest in optimization and profiling for ActionScript 3.0 and Flex development. I've been piecing together ActionScript optimization techniques and practices from around the web for a couple years now. Some of these techniques are in opposition to what the standards dictate but most of software development is this way. You have to learn when to use some techniques and when to leave some out.

    Here is a round up of ActionScript 3.0 and Flex optimization techniques and practices. I’ve scoured the web for and filtered practices and techniques that can be adopted into your application development process.

    =======================================================

    前面说的全是屁话下面才是例子说明!很重要:

    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()初始化,而不要直接在构造函数里初始化!
  • 相关阅读:
    spring框架面试
    为什么人们都讨厌开会?
    使用IDEA连接远程主机上的Redis失败. 抛出redis.clients.jedis.exceptions.JedisConnectionException: Failed connecting to host xxx
    192405实验六 Metasploit攻击渗透实践
    实验七 网络欺诈与防范
    gradle implementation、compileOnly、api
    C# 数组对比和字符串分割后转成指定类型的数组
    sql 2012 的 问题 无法 打开的原因。
    PhpStudyV8新版本_Win安装PHP扩展
    算法相关
  • 原文地址:https://www.cnblogs.com/xinqingHappy/p/2980348.html
Copyright © 2020-2023  润新知