zoukankan      html  css  js  c++  java
  • 有助于改善性能的技巧(1)

    (1)慎用异常

        在java软件开发中,经常使用try-catch进行错误捕获,但是,try-catch语句对系统性能而言是非常糟糕的。虽然在一次try-catch中,无法察觉到它对性能带来的损失,但是,一旦try-catch语句被用于循环之中,就会给系能性能带来极大的伤害。

       以下是一段将try-catch应用用于for循环体内的示例代码:

    int a=0;
    for(int i=0;i<1000000000;i++){ 
          try{
            a++;
         }catch(Exception e){
       }
    }

    在这段代码中,循环体内只进行了简单的计算。如果尝试将try-catch移到循环体外,那么就能提升系统性能,如下代码:

    int a=0;
    try{
      for(int i=0;i<100000000;i++){
          a++;
      }
    }catch(Exception e){
    }

     
    (2)使用局部变量

    调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中,速度较快,其他变量,如静态变量,实例变量等,都在堆中创建,速度较慢。

    下面是一段使用局部变量进行计算的代码:

    将局部变量替换为类的静态变量:

    public static int ta=0;
    for(int i=0;i<10000000;i++){
       ta++;
    }

    第一段代码相对耗时78ms,而第二段使用类变量的代码相对耗时266ms,由此可见,局部变量的访问速度远远高于类的成员变量。

    (3)位元素代替乘除法。

    在所有运算符中吗,位运算是最为高效的。因此,可以尝试使用位运算代替部分算术运算,来提高系统的运算速度。最典型的就是对于整数的乘除法运算优化。

    以下是使用算术运算的实现:

    long a=100;
    for(int i=0;i<10000000;i++){
       a*=2;
       a/=2;    
    }

    将循环体中的乘除运算改为等价的位运算,代码如下:

    long a=100;
    for(int i=0;i<10000000;i++){
       a<<=1;
       a>>=1;
    }

    两段代码执行了完全相同的功能,在每次循环中,都将整数乘以2,并除以2。在这若干次循环中,第一段代码相对耗时219ms,而第二段使用位运算的代码相对耗时31ms。

    (4)替换switch

    关键字switch语句用于多条件判断,switch语句的功能类似于if-else语句,两者的性能也差不多。因此,不能说switch语句会降低系统的性能。但是,在绝大部分情况下,switch语句还是有性能提升的空间。

    来看下面的例子:

    int re=0;
    for(int i=0;i<100000000;i++){
      re = switchInt(i);
    }
    protected int switchInt(int z){
       int i=z%10+1;
       switch(i){
          case 1:return 3;
          case 2:return 6;
          case 3:return 7;
          case 4:return 8;
          case 5:return 10;
          case 6:return 16;
          case 7:return 18;
          case 8:return 44;
          default:return -1;
       }
    }

    上面中,对一个switch操作进行了若干次循环。这种switch模式性能并不差,但是如果换一种全新的思路替代switch,实现相同的程序功能,那么性能有很大的提升,以下代码实现了与上例switch语句相同的功能:

    int re=0;
    int[] sw= new int[]{0,3,6,7,8,10,16,18,44};
    for(int i=0;i<100000000;i++){
        re=arrayInt(sw,i);
    }
    protected int arrayInt(int[] sw,int z){
        int i=z%10+1;
        if(i>7||i<1)
           return -1;
        else
           return  sw[i];
    }

    以上使用全新的思路,使用一个连续的数组代替了switch语句。因为对数组的随机访问是非常快的,至少好于switch的分支判断,因此它的速度一定快于原来的实现。

    (5)提取表达式

       在软件开发中,程序员很容易有意无意地让代码做一些"重复劳动",在大部分情况下,由于计算机的高速运行,这些"重复劳动"并不会对性能构成太大的威胁,但若希望系统性能发挥到极致,提取这些"重复劳动"相当有意义。比如以下代码中进行了两次算术计算:

    double d=Math.random();
    double a=Math.random();
    double b=Math.random();
    double e=Math.random();
    double x,y;
    for(int i=0;i<100000000;i++){
       x=d*a*b/3*4*a;
       y=e*a*b/3*4*a;
    }

    改进后的代码如下:

    double d=Math.random();
    double a=Math.random();
    double b=Math.random();
    double e=Math.random();
    double t,x,y;
    for(int i=0;i<100000000;i++){
        t = a*b/3*4*a;
        x= d*t;
        y= e*t;   
    }

    在以上的代码中,提取了原表达式的公共部分,使得每次循环计算只执行一次,可见提取复杂的重复操作是相当有意义的。同理如果在某个循环中需要执行一个耗时操作,而在循环体内,其执行结果总是唯一的,也应该提取到循环体外。

    (6)展开循环

      与前面所介绍的优化技巧略有不同,展开循环是一种在极端情况下使用的优化手段,因为展开循环很可能会影响代码的可读性和可维护性,而这两者对软件系统来说也是极为重要,但是,当性能问题成为系统的主要矛盾时,展开循环绝对是一种值得尝试的技巧。

    一个普通的循环代码段如下:

    int[] array= new int[999999999];
    for(int i=0;i<999999999;i++){
        array[i]=i;
    }

    展开循环后,类似于以下格式:

    int[] array= new int[999999999];
    for(int i=0;i<999999999;i+=3){
        array[i]=i;
        array[i+1]=i+1;
        array[i+2]=i+2;
    }

    以上两段代码功能完全相同,但第二段代码进行了循环展开的优化,在一个循环体内处理了原来代码中的3个循环逻辑。减少了循环次数,对提升系统性能很有帮助。

    (7)布尔运算代替位运算

       虽然位运算的速度远远高于算术运算,但是在条件判断时,使用位运算替代布尔运算却是非常错误的选择。

       在条件判断时,java会对布尔运算做相当充分的优化。假设有表达式a,b,c进行布尔运算"a&&b&&c",根据逻辑与的特点,只要在整个布尔表达式中有一项返回false,整个表达式就会返回false.因此,当表达式a为false时,该表达式将立即返回false,而不会再去计算表达式b和c,若此时,表达式b,c需要消耗大量的系统资源,这种处理方式可以节省这些计算资源。

       同理,当计算表达式"a||b||c"时,只要a,b,或c,3个表达式其中任意一个计算结果为true时,整体表达式立即返回true,而不去计算剩余表达式。

  • 相关阅读:
    JS定时器相关用法
    asp.net 使用DroDownList来实现二级联动
    移动端页面开发流程
    使用DataList实现数据分页的技术
    使用CSS3制作三角形小图标
    JS面向对象
    JS封闭函数、闭包、内置对象
    封装自己的DB类(PHP)
    github之文件的三种状态关系
    Windows Socket编程笔记之最简单的小Demo
  • 原文地址:https://www.cnblogs.com/sierrajuan/p/3650702.html
Copyright © 2011-2022 走看看